remove stuff
This commit is contained in:
parent
1665b57e14
commit
5976fdfe42
636 changed files with 0 additions and 108555 deletions
|
@ -1,21 +0,0 @@
|
|||
|
||||
# http://python.org/sf/1413192
|
||||
#
|
||||
# This test relies on the variable names, see the bug report for details.
|
||||
# The problem was that the env was deallocated prior to the txn.
|
||||
|
||||
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 = '.'
|
||||
|
||||
env = db.DBEnv()
|
||||
env.open(env_name, db.DB_CREATE | db.DB_INIT_TXN | db.DB_INIT_MPOOL)
|
||||
the_txn = env.txn_begin()
|
||||
|
||||
map = db.DB(env)
|
||||
map.open('xxx.db', "p", db.DB_HASH, db.DB_CREATE, 0666, txn=the_txn)
|
|
@ -1,91 +0,0 @@
|
|||
"""Run all test cases.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import unittest
|
||||
try:
|
||||
# For Pythons w/distutils pybsddb
|
||||
from bsddb3 import db
|
||||
except ImportError:
|
||||
# For Python 2.3
|
||||
from bsddb import db
|
||||
|
||||
verbose = 0
|
||||
if 'verbose' in sys.argv:
|
||||
verbose = 1
|
||||
sys.argv.remove('verbose')
|
||||
|
||||
if 'silent' in sys.argv: # take care of old flag, just in case
|
||||
verbose = 0
|
||||
sys.argv.remove('silent')
|
||||
|
||||
|
||||
def print_versions():
|
||||
print
|
||||
print '-=' * 38
|
||||
print db.DB_VERSION_STRING
|
||||
print 'bsddb.db.version(): %s' % (db.version(), )
|
||||
print 'bsddb.db.__version__: %s' % db.__version__
|
||||
print 'bsddb.db.cvsid: %s' % db.cvsid
|
||||
print 'python version: %s' % sys.version
|
||||
print 'My pid: %s' % os.getpid()
|
||||
print '-=' * 38
|
||||
|
||||
|
||||
class PrintInfoFakeTest(unittest.TestCase):
|
||||
def testPrintVersions(self):
|
||||
print_versions()
|
||||
|
||||
|
||||
# This little hack is for when this module is run as main and all the
|
||||
# other modules import it so they will still be able to get the right
|
||||
# verbose setting. It's confusing but it works.
|
||||
import test_all
|
||||
test_all.verbose = verbose
|
||||
|
||||
|
||||
def suite():
|
||||
try:
|
||||
# this is special, it used to segfault the interpreter
|
||||
import test_1413192
|
||||
except:
|
||||
pass
|
||||
|
||||
test_modules = [
|
||||
'test_associate',
|
||||
'test_basics',
|
||||
'test_compat',
|
||||
'test_compare',
|
||||
'test_dbobj',
|
||||
'test_dbshelve',
|
||||
'test_dbtables',
|
||||
'test_env_close',
|
||||
'test_get_none',
|
||||
'test_join',
|
||||
'test_lock',
|
||||
'test_misc',
|
||||
'test_pickle',
|
||||
'test_queue',
|
||||
'test_recno',
|
||||
'test_thread',
|
||||
'test_sequence',
|
||||
'test_cursor_pget_bug',
|
||||
]
|
||||
|
||||
alltests = unittest.TestSuite()
|
||||
for name in test_modules:
|
||||
module = __import__(name)
|
||||
alltests.addTest(module.test_suite())
|
||||
return alltests
|
||||
|
||||
|
||||
def test_suite():
|
||||
suite = unittest.TestSuite()
|
||||
suite.addTest(unittest.makeSuite(PrintInfoFakeTest))
|
||||
return suite
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print_versions()
|
||||
unittest.main(defaultTest='suite')
|
|
@ -1,478 +0,0 @@
|
|||
"""
|
||||
TestCases for DB.associate.
|
||||
"""
|
||||
|
||||
import sys, os, string
|
||||
import tempfile
|
||||
import time
|
||||
from pprint import pprint
|
||||
|
||||
try:
|
||||
from threading import Thread, currentThread
|
||||
have_threads = 1
|
||||
except ImportError:
|
||||
have_threads = 0
|
||||
|
||||
import unittest
|
||||
from test_all import verbose
|
||||
|
||||
try:
|
||||
# For Pythons w/distutils pybsddb
|
||||
from bsddb3 import db, dbshelve
|
||||
except ImportError:
|
||||
# For Python 2.3
|
||||
from bsddb import db, dbshelve
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
|
||||
musicdata = {
|
||||
1 : ("Bad English", "The Price Of Love", "Rock"),
|
||||
2 : ("DNA featuring Suzanne Vega", "Tom's Diner", "Rock"),
|
||||
3 : ("George Michael", "Praying For Time", "Rock"),
|
||||
4 : ("Gloria Estefan", "Here We Are", "Rock"),
|
||||
5 : ("Linda Ronstadt", "Don't Know Much", "Rock"),
|
||||
6 : ("Michael Bolton", "How Am I Supposed To Live Without You", "Blues"),
|
||||
7 : ("Paul Young", "Oh Girl", "Rock"),
|
||||
8 : ("Paula Abdul", "Opposites Attract", "Rock"),
|
||||
9 : ("Richard Marx", "Should've Known Better", "Rock"),
|
||||
10: ("Rod Stewart", "Forever Young", "Rock"),
|
||||
11: ("Roxette", "Dangerous", "Rock"),
|
||||
12: ("Sheena Easton", "The Lover In Me", "Rock"),
|
||||
13: ("Sinead O'Connor", "Nothing Compares 2 U", "Rock"),
|
||||
14: ("Stevie B.", "Because I Love You", "Rock"),
|
||||
15: ("Taylor Dayne", "Love Will Lead You Back", "Rock"),
|
||||
16: ("The Bangles", "Eternal Flame", "Rock"),
|
||||
17: ("Wilson Phillips", "Release Me", "Rock"),
|
||||
18: ("Billy Joel", "Blonde Over Blue", "Rock"),
|
||||
19: ("Billy Joel", "Famous Last Words", "Rock"),
|
||||
20: ("Billy Joel", "Lullabye (Goodnight, My Angel)", "Rock"),
|
||||
21: ("Billy Joel", "The River Of Dreams", "Rock"),
|
||||
22: ("Billy Joel", "Two Thousand Years", "Rock"),
|
||||
23: ("Janet Jackson", "Alright", "Rock"),
|
||||
24: ("Janet Jackson", "Black Cat", "Rock"),
|
||||
25: ("Janet Jackson", "Come Back To Me", "Rock"),
|
||||
26: ("Janet Jackson", "Escapade", "Rock"),
|
||||
27: ("Janet Jackson", "Love Will Never Do (Without You)", "Rock"),
|
||||
28: ("Janet Jackson", "Miss You Much", "Rock"),
|
||||
29: ("Janet Jackson", "Rhythm Nation", "Rock"),
|
||||
30: ("Janet Jackson", "State Of The World", "Rock"),
|
||||
31: ("Janet Jackson", "The Knowledge", "Rock"),
|
||||
32: ("Spyro Gyra", "End of Romanticism", "Jazz"),
|
||||
33: ("Spyro Gyra", "Heliopolis", "Jazz"),
|
||||
34: ("Spyro Gyra", "Jubilee", "Jazz"),
|
||||
35: ("Spyro Gyra", "Little Linda", "Jazz"),
|
||||
36: ("Spyro Gyra", "Morning Dance", "Jazz"),
|
||||
37: ("Spyro Gyra", "Song for Lorraine", "Jazz"),
|
||||
38: ("Yes", "Owner Of A Lonely Heart", "Rock"),
|
||||
39: ("Yes", "Rhythm Of Love", "Rock"),
|
||||
40: ("Cusco", "Dream Catcher", "New Age"),
|
||||
41: ("Cusco", "Geronimos Laughter", "New Age"),
|
||||
42: ("Cusco", "Ghost Dance", "New Age"),
|
||||
43: ("Blue Man Group", "Drumbone", "New Age"),
|
||||
44: ("Blue Man Group", "Endless Column", "New Age"),
|
||||
45: ("Blue Man Group", "Klein Mandelbrot", "New Age"),
|
||||
46: ("Kenny G", "Silhouette", "Jazz"),
|
||||
47: ("Sade", "Smooth Operator", "Jazz"),
|
||||
48: ("David Arkenstone", "Papillon (On The Wings Of The Butterfly)",
|
||||
"New Age"),
|
||||
49: ("David Arkenstone", "Stepping Stars", "New Age"),
|
||||
50: ("David Arkenstone", "Carnation Lily Lily Rose", "New Age"),
|
||||
51: ("David Lanz", "Behind The Waterfall", "New Age"),
|
||||
52: ("David Lanz", "Cristofori's Dream", "New Age"),
|
||||
53: ("David Lanz", "Heartsounds", "New Age"),
|
||||
54: ("David Lanz", "Leaves on the Seine", "New Age"),
|
||||
99: ("unknown artist", "Unnamed song", "Unknown"),
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
class AssociateErrorTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.filename = self.__class__.__name__ + '.db'
|
||||
homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
|
||||
self.homeDir = homeDir
|
||||
try:
|
||||
os.mkdir(homeDir)
|
||||
except os.error:
|
||||
import glob
|
||||
files = glob.glob(os.path.join(self.homeDir, '*'))
|
||||
for file in files:
|
||||
os.remove(file)
|
||||
self.env = db.DBEnv()
|
||||
self.env.open(homeDir, db.DB_CREATE | db.DB_INIT_MPOOL)
|
||||
|
||||
def tearDown(self):
|
||||
self.env.close()
|
||||
self.env = None
|
||||
import glob
|
||||
files = glob.glob(os.path.join(self.homeDir, '*'))
|
||||
for file in files:
|
||||
os.remove(file)
|
||||
|
||||
|
||||
def test00_associateDBError(self):
|
||||
if verbose:
|
||||
print '\n', '-=' * 30
|
||||
print "Running %s.test00_associateDBError..." % \
|
||||
self.__class__.__name__
|
||||
|
||||
dupDB = db.DB(self.env)
|
||||
dupDB.set_flags(db.DB_DUP)
|
||||
dupDB.open(self.filename, "primary", db.DB_BTREE, db.DB_CREATE)
|
||||
|
||||
secDB = db.DB(self.env)
|
||||
secDB.open(self.filename, "secondary", db.DB_BTREE, db.DB_CREATE)
|
||||
|
||||
# dupDB has been configured to allow duplicates, it can't
|
||||
# associate with a secondary. BerkeleyDB will return an error.
|
||||
try:
|
||||
def f(a,b): return a+b
|
||||
dupDB.associate(secDB, f)
|
||||
except db.DBError:
|
||||
# good
|
||||
secDB.close()
|
||||
dupDB.close()
|
||||
else:
|
||||
secDB.close()
|
||||
dupDB.close()
|
||||
self.fail("DBError exception was expected")
|
||||
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
|
||||
class AssociateTestCase(unittest.TestCase):
|
||||
keytype = ''
|
||||
envFlags = 0
|
||||
dbFlags = 0
|
||||
|
||||
def setUp(self):
|
||||
self.filename = self.__class__.__name__ + '.db'
|
||||
homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
|
||||
self.homeDir = homeDir
|
||||
try:
|
||||
os.mkdir(homeDir)
|
||||
except os.error:
|
||||
import glob
|
||||
files = glob.glob(os.path.join(self.homeDir, '*'))
|
||||
for file in files:
|
||||
os.remove(file)
|
||||
self.env = db.DBEnv()
|
||||
self.env.open(homeDir, db.DB_CREATE | db.DB_INIT_MPOOL |
|
||||
db.DB_INIT_LOCK | db.DB_THREAD | self.envFlags)
|
||||
|
||||
def tearDown(self):
|
||||
self.closeDB()
|
||||
self.env.close()
|
||||
self.env = None
|
||||
import glob
|
||||
files = glob.glob(os.path.join(self.homeDir, '*'))
|
||||
for file in files:
|
||||
os.remove(file)
|
||||
|
||||
def addDataToDB(self, d, txn=None):
|
||||
for key, value in musicdata.items():
|
||||
if type(self.keytype) == type(''):
|
||||
key = "%02d" % key
|
||||
d.put(key, string.join(value, '|'), txn=txn)
|
||||
|
||||
def createDB(self, txn=None):
|
||||
self.cur = None
|
||||
self.secDB = None
|
||||
self.primary = db.DB(self.env)
|
||||
self.primary.set_get_returns_none(2)
|
||||
if db.version() >= (4, 1):
|
||||
self.primary.open(self.filename, "primary", self.dbtype,
|
||||
db.DB_CREATE | db.DB_THREAD | self.dbFlags, txn=txn)
|
||||
else:
|
||||
self.primary.open(self.filename, "primary", self.dbtype,
|
||||
db.DB_CREATE | db.DB_THREAD | self.dbFlags)
|
||||
|
||||
def closeDB(self):
|
||||
if self.cur:
|
||||
self.cur.close()
|
||||
self.cur = None
|
||||
if self.secDB:
|
||||
self.secDB.close()
|
||||
self.secDB = None
|
||||
self.primary.close()
|
||||
self.primary = None
|
||||
|
||||
def getDB(self):
|
||||
return self.primary
|
||||
|
||||
|
||||
def test01_associateWithDB(self):
|
||||
if verbose:
|
||||
print '\n', '-=' * 30
|
||||
print "Running %s.test01_associateWithDB..." % \
|
||||
self.__class__.__name__
|
||||
|
||||
self.createDB()
|
||||
|
||||
self.secDB = db.DB(self.env)
|
||||
self.secDB.set_flags(db.DB_DUP)
|
||||
self.secDB.set_get_returns_none(2)
|
||||
self.secDB.open(self.filename, "secondary", db.DB_BTREE,
|
||||
db.DB_CREATE | db.DB_THREAD | self.dbFlags)
|
||||
self.getDB().associate(self.secDB, self.getGenre)
|
||||
|
||||
self.addDataToDB(self.getDB())
|
||||
|
||||
self.finish_test(self.secDB)
|
||||
|
||||
|
||||
def test02_associateAfterDB(self):
|
||||
if verbose:
|
||||
print '\n', '-=' * 30
|
||||
print "Running %s.test02_associateAfterDB..." % \
|
||||
self.__class__.__name__
|
||||
|
||||
self.createDB()
|
||||
self.addDataToDB(self.getDB())
|
||||
|
||||
self.secDB = db.DB(self.env)
|
||||
self.secDB.set_flags(db.DB_DUP)
|
||||
self.secDB.open(self.filename, "secondary", db.DB_BTREE,
|
||||
db.DB_CREATE | db.DB_THREAD | self.dbFlags)
|
||||
|
||||
# adding the DB_CREATE flag will cause it to index existing records
|
||||
self.getDB().associate(self.secDB, self.getGenre, db.DB_CREATE)
|
||||
|
||||
self.finish_test(self.secDB)
|
||||
|
||||
|
||||
def finish_test(self, secDB, txn=None):
|
||||
# 'Blues' should not be in the secondary database
|
||||
vals = secDB.pget('Blues', txn=txn)
|
||||
assert vals == None, vals
|
||||
|
||||
vals = secDB.pget('Unknown', txn=txn)
|
||||
assert vals[0] == 99 or vals[0] == '99', vals
|
||||
vals[1].index('Unknown')
|
||||
vals[1].index('Unnamed')
|
||||
vals[1].index('unknown')
|
||||
|
||||
if verbose:
|
||||
print "Primary key traversal:"
|
||||
self.cur = self.getDB().cursor(txn)
|
||||
count = 0
|
||||
rec = self.cur.first()
|
||||
while rec is not None:
|
||||
if type(self.keytype) == type(''):
|
||||
assert string.atoi(rec[0]) # for primary db, key is a number
|
||||
else:
|
||||
assert rec[0] and type(rec[0]) == type(0)
|
||||
count = count + 1
|
||||
if verbose:
|
||||
print rec
|
||||
rec = self.cur.next()
|
||||
assert count == len(musicdata) # all items accounted for
|
||||
|
||||
|
||||
if verbose:
|
||||
print "Secondary key traversal:"
|
||||
self.cur = secDB.cursor(txn)
|
||||
count = 0
|
||||
|
||||
# test cursor pget
|
||||
vals = self.cur.pget('Unknown', flags=db.DB_LAST)
|
||||
assert vals[1] == 99 or vals[1] == '99', vals
|
||||
assert vals[0] == 'Unknown'
|
||||
vals[2].index('Unknown')
|
||||
vals[2].index('Unnamed')
|
||||
vals[2].index('unknown')
|
||||
|
||||
vals = self.cur.pget('Unknown', data='wrong value', flags=db.DB_GET_BOTH)
|
||||
assert vals == None, vals
|
||||
|
||||
rec = self.cur.first()
|
||||
assert rec[0] == "Jazz"
|
||||
while rec is not None:
|
||||
count = count + 1
|
||||
if verbose:
|
||||
print rec
|
||||
rec = self.cur.next()
|
||||
# all items accounted for EXCEPT for 1 with "Blues" genre
|
||||
assert count == len(musicdata)-1
|
||||
|
||||
self.cur = None
|
||||
|
||||
def getGenre(self, priKey, priData):
|
||||
assert type(priData) == type("")
|
||||
if verbose:
|
||||
print 'getGenre key: %r data: %r' % (priKey, priData)
|
||||
genre = string.split(priData, '|')[2]
|
||||
if genre == 'Blues':
|
||||
return db.DB_DONOTINDEX
|
||||
else:
|
||||
return genre
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
|
||||
class AssociateHashTestCase(AssociateTestCase):
|
||||
dbtype = db.DB_HASH
|
||||
|
||||
class AssociateBTreeTestCase(AssociateTestCase):
|
||||
dbtype = db.DB_BTREE
|
||||
|
||||
class AssociateRecnoTestCase(AssociateTestCase):
|
||||
dbtype = db.DB_RECNO
|
||||
keytype = 0
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
class AssociateBTreeTxnTestCase(AssociateBTreeTestCase):
|
||||
envFlags = db.DB_INIT_TXN
|
||||
dbFlags = 0
|
||||
|
||||
def txn_finish_test(self, sDB, txn):
|
||||
try:
|
||||
self.finish_test(sDB, txn=txn)
|
||||
finally:
|
||||
if self.cur:
|
||||
self.cur.close()
|
||||
self.cur = None
|
||||
if txn:
|
||||
txn.commit()
|
||||
|
||||
def test13_associate_in_transaction(self):
|
||||
if verbose:
|
||||
print '\n', '-=' * 30
|
||||
print "Running %s.test13_associateAutoCommit..." % \
|
||||
self.__class__.__name__
|
||||
|
||||
txn = self.env.txn_begin()
|
||||
try:
|
||||
self.createDB(txn=txn)
|
||||
|
||||
self.secDB = db.DB(self.env)
|
||||
self.secDB.set_flags(db.DB_DUP)
|
||||
self.secDB.set_get_returns_none(2)
|
||||
self.secDB.open(self.filename, "secondary", db.DB_BTREE,
|
||||
db.DB_CREATE | db.DB_THREAD, txn=txn)
|
||||
if db.version() >= (4,1):
|
||||
self.getDB().associate(self.secDB, self.getGenre, txn=txn)
|
||||
else:
|
||||
self.getDB().associate(self.secDB, self.getGenre)
|
||||
|
||||
self.addDataToDB(self.getDB(), txn=txn)
|
||||
except:
|
||||
txn.abort()
|
||||
raise
|
||||
|
||||
self.txn_finish_test(self.secDB, txn=txn)
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
class ShelveAssociateTestCase(AssociateTestCase):
|
||||
|
||||
def createDB(self):
|
||||
self.primary = dbshelve.open(self.filename,
|
||||
dbname="primary",
|
||||
dbenv=self.env,
|
||||
filetype=self.dbtype)
|
||||
|
||||
def addDataToDB(self, d):
|
||||
for key, value in musicdata.items():
|
||||
if type(self.keytype) == type(''):
|
||||
key = "%02d" % key
|
||||
d.put(key, value) # save the value as is this time
|
||||
|
||||
|
||||
def getGenre(self, priKey, priData):
|
||||
assert type(priData) == type(())
|
||||
if verbose:
|
||||
print 'getGenre key: %r data: %r' % (priKey, priData)
|
||||
genre = priData[2]
|
||||
if genre == 'Blues':
|
||||
return db.DB_DONOTINDEX
|
||||
else:
|
||||
return genre
|
||||
|
||||
|
||||
class ShelveAssociateHashTestCase(ShelveAssociateTestCase):
|
||||
dbtype = db.DB_HASH
|
||||
|
||||
class ShelveAssociateBTreeTestCase(ShelveAssociateTestCase):
|
||||
dbtype = db.DB_BTREE
|
||||
|
||||
class ShelveAssociateRecnoTestCase(ShelveAssociateTestCase):
|
||||
dbtype = db.DB_RECNO
|
||||
keytype = 0
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
class ThreadedAssociateTestCase(AssociateTestCase):
|
||||
|
||||
def addDataToDB(self, d):
|
||||
t1 = Thread(target = self.writer1,
|
||||
args = (d, ))
|
||||
t2 = Thread(target = self.writer2,
|
||||
args = (d, ))
|
||||
|
||||
t1.start()
|
||||
t2.start()
|
||||
t1.join()
|
||||
t2.join()
|
||||
|
||||
def writer1(self, d):
|
||||
for key, value in musicdata.items():
|
||||
if type(self.keytype) == type(''):
|
||||
key = "%02d" % key
|
||||
d.put(key, string.join(value, '|'))
|
||||
|
||||
def writer2(self, d):
|
||||
for x in range(100, 600):
|
||||
key = 'z%2d' % x
|
||||
value = [key] * 4
|
||||
d.put(key, string.join(value, '|'))
|
||||
|
||||
|
||||
class ThreadedAssociateHashTestCase(ShelveAssociateTestCase):
|
||||
dbtype = db.DB_HASH
|
||||
|
||||
class ThreadedAssociateBTreeTestCase(ShelveAssociateTestCase):
|
||||
dbtype = db.DB_BTREE
|
||||
|
||||
class ThreadedAssociateRecnoTestCase(ShelveAssociateTestCase):
|
||||
dbtype = db.DB_RECNO
|
||||
keytype = 0
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
def test_suite():
|
||||
suite = unittest.TestSuite()
|
||||
|
||||
if db.version() >= (3, 3, 11):
|
||||
suite.addTest(unittest.makeSuite(AssociateErrorTestCase))
|
||||
|
||||
suite.addTest(unittest.makeSuite(AssociateHashTestCase))
|
||||
suite.addTest(unittest.makeSuite(AssociateBTreeTestCase))
|
||||
suite.addTest(unittest.makeSuite(AssociateRecnoTestCase))
|
||||
|
||||
if db.version() >= (4, 1):
|
||||
suite.addTest(unittest.makeSuite(AssociateBTreeTxnTestCase))
|
||||
|
||||
suite.addTest(unittest.makeSuite(ShelveAssociateHashTestCase))
|
||||
suite.addTest(unittest.makeSuite(ShelveAssociateBTreeTestCase))
|
||||
suite.addTest(unittest.makeSuite(ShelveAssociateRecnoTestCase))
|
||||
|
||||
if have_threads:
|
||||
suite.addTest(unittest.makeSuite(ThreadedAssociateHashTestCase))
|
||||
suite.addTest(unittest.makeSuite(ThreadedAssociateBTreeTestCase))
|
||||
suite.addTest(unittest.makeSuite(ThreadedAssociateRecnoTestCase))
|
||||
|
||||
return suite
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(defaultTest='test_suite')
|
|
@ -1,989 +0,0 @@
|
|||
"""
|
||||
Basic TestCases for BTree and hash DBs, with and without a DBEnv, with
|
||||
various DB flags, etc.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import errno
|
||||
import shutil
|
||||
import string
|
||||
import tempfile
|
||||
from pprint import pprint
|
||||
import unittest
|
||||
import time
|
||||
|
||||
try:
|
||||
# For Pythons w/distutils pybsddb
|
||||
from bsddb3 import db
|
||||
except ImportError:
|
||||
# For Python 2.3
|
||||
from bsddb import db
|
||||
|
||||
from test_all import verbose
|
||||
|
||||
DASH = '-'
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
class VersionTestCase(unittest.TestCase):
|
||||
def test00_version(self):
|
||||
info = db.version()
|
||||
if verbose:
|
||||
print '\n', '-=' * 20
|
||||
print 'bsddb.db.version(): %s' % (info, )
|
||||
print db.DB_VERSION_STRING
|
||||
print '-=' * 20
|
||||
assert info == (db.DB_VERSION_MAJOR, db.DB_VERSION_MINOR,
|
||||
db.DB_VERSION_PATCH)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
class BasicTestCase(unittest.TestCase):
|
||||
dbtype = db.DB_UNKNOWN # must be set in derived class
|
||||
dbopenflags = 0
|
||||
dbsetflags = 0
|
||||
dbmode = 0660
|
||||
dbname = None
|
||||
useEnv = 0
|
||||
envflags = 0
|
||||
envsetflags = 0
|
||||
|
||||
_numKeys = 1002 # PRIVATE. NOTE: must be an even value
|
||||
|
||||
def setUp(self):
|
||||
if self.useEnv:
|
||||
homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
|
||||
self.homeDir = homeDir
|
||||
try:
|
||||
shutil.rmtree(homeDir)
|
||||
except OSError, e:
|
||||
# unix returns ENOENT, windows returns ESRCH
|
||||
if e.errno not in (errno.ENOENT, errno.ESRCH): raise
|
||||
os.mkdir(homeDir)
|
||||
try:
|
||||
self.env = db.DBEnv()
|
||||
self.env.set_lg_max(1024*1024)
|
||||
self.env.set_tx_max(30)
|
||||
self.env.set_tx_timestamp(int(time.time()))
|
||||
self.env.set_flags(self.envsetflags, 1)
|
||||
self.env.open(homeDir, self.envflags | db.DB_CREATE)
|
||||
tempfile.tempdir = homeDir
|
||||
self.filename = os.path.split(tempfile.mktemp())[1]
|
||||
tempfile.tempdir = None
|
||||
# Yes, a bare except is intended, since we're re-raising the exc.
|
||||
except:
|
||||
shutil.rmtree(homeDir)
|
||||
raise
|
||||
else:
|
||||
self.env = None
|
||||
self.filename = tempfile.mktemp()
|
||||
|
||||
# create and open the DB
|
||||
self.d = db.DB(self.env)
|
||||
self.d.set_flags(self.dbsetflags)
|
||||
if self.dbname:
|
||||
self.d.open(self.filename, self.dbname, self.dbtype,
|
||||
self.dbopenflags|db.DB_CREATE, self.dbmode)
|
||||
else:
|
||||
self.d.open(self.filename, # try out keyword args
|
||||
mode = self.dbmode,
|
||||
dbtype = self.dbtype,
|
||||
flags = self.dbopenflags|db.DB_CREATE)
|
||||
|
||||
self.populateDB()
|
||||
|
||||
|
||||
def tearDown(self):
|
||||
self.d.close()
|
||||
if self.env is not None:
|
||||
self.env.close()
|
||||
shutil.rmtree(self.homeDir)
|
||||
## Make a new DBEnv to remove the env files from the home dir.
|
||||
## (It can't be done while the env is open, nor after it has been
|
||||
## closed, so we make a new one to do it.)
|
||||
#e = db.DBEnv()
|
||||
#e.remove(self.homeDir)
|
||||
#os.remove(os.path.join(self.homeDir, self.filename))
|
||||
else:
|
||||
os.remove(self.filename)
|
||||
|
||||
|
||||
|
||||
def populateDB(self, _txn=None):
|
||||
d = self.d
|
||||
|
||||
for x in range(self._numKeys/2):
|
||||
key = '%04d' % (self._numKeys - x) # insert keys in reverse order
|
||||
data = self.makeData(key)
|
||||
d.put(key, data, _txn)
|
||||
|
||||
d.put('empty value', '', _txn)
|
||||
|
||||
for x in range(self._numKeys/2-1):
|
||||
key = '%04d' % x # and now some in forward order
|
||||
data = self.makeData(key)
|
||||
d.put(key, data, _txn)
|
||||
|
||||
if _txn:
|
||||
_txn.commit()
|
||||
|
||||
num = len(d)
|
||||
if verbose:
|
||||
print "created %d records" % num
|
||||
|
||||
|
||||
def makeData(self, key):
|
||||
return DASH.join([key] * 5)
|
||||
|
||||
|
||||
|
||||
#----------------------------------------
|
||||
|
||||
def test01_GetsAndPuts(self):
|
||||
d = self.d
|
||||
|
||||
if verbose:
|
||||
print '\n', '-=' * 30
|
||||
print "Running %s.test01_GetsAndPuts..." % self.__class__.__name__
|
||||
|
||||
for key in ['0001', '0100', '0400', '0700', '0999']:
|
||||
data = d.get(key)
|
||||
if verbose:
|
||||
print data
|
||||
|
||||
assert d.get('0321') == '0321-0321-0321-0321-0321'
|
||||
|
||||
# By default non-existant keys return None...
|
||||
assert d.get('abcd') == None
|
||||
|
||||
# ...but they raise exceptions in other situations. Call
|
||||
# set_get_returns_none() to change it.
|
||||
try:
|
||||
d.delete('abcd')
|
||||
except db.DBNotFoundError, val:
|
||||
assert val[0] == db.DB_NOTFOUND
|
||||
if verbose: print val
|
||||
else:
|
||||
self.fail("expected exception")
|
||||
|
||||
|
||||
d.put('abcd', 'a new record')
|
||||
assert d.get('abcd') == 'a new record'
|
||||
|
||||
d.put('abcd', 'same key')
|
||||
if self.dbsetflags & db.DB_DUP:
|
||||
assert d.get('abcd') == 'a new record'
|
||||
else:
|
||||
assert d.get('abcd') == 'same key'
|
||||
|
||||
|
||||
try:
|
||||
d.put('abcd', 'this should fail', flags=db.DB_NOOVERWRITE)
|
||||
except db.DBKeyExistError, val:
|
||||
assert val[0] == db.DB_KEYEXIST
|
||||
if verbose: print val
|
||||
else:
|
||||
self.fail("expected exception")
|
||||
|
||||
if self.dbsetflags & db.DB_DUP:
|
||||
assert d.get('abcd') == 'a new record'
|
||||
else:
|
||||
assert d.get('abcd') == 'same key'
|
||||
|
||||
|
||||
d.sync()
|
||||
d.close()
|
||||
del d
|
||||
|
||||
self.d = db.DB(self.env)
|
||||
if self.dbname:
|
||||
self.d.open(self.filename, self.dbname)
|
||||
else:
|
||||
self.d.open(self.filename)
|
||||
d = self.d
|
||||
|
||||
assert d.get('0321') == '0321-0321-0321-0321-0321'
|
||||
if self.dbsetflags & db.DB_DUP:
|
||||
assert d.get('abcd') == 'a new record'
|
||||
else:
|
||||
assert d.get('abcd') == 'same key'
|
||||
|
||||
rec = d.get_both('0555', '0555-0555-0555-0555-0555')
|
||||
if verbose:
|
||||
print rec
|
||||
|
||||
assert d.get_both('0555', 'bad data') == None
|
||||
|
||||
# test default value
|
||||
data = d.get('bad key', 'bad data')
|
||||
assert data == 'bad data'
|
||||
|
||||
# any object can pass through
|
||||
data = d.get('bad key', self)
|
||||
assert data == self
|
||||
|
||||
s = d.stat()
|
||||
assert type(s) == type({})
|
||||
if verbose:
|
||||
print 'd.stat() returned this dictionary:'
|
||||
pprint(s)
|
||||
|
||||
|
||||
#----------------------------------------
|
||||
|
||||
def test02_DictionaryMethods(self):
|
||||
d = self.d
|
||||
|
||||
if verbose:
|
||||
print '\n', '-=' * 30
|
||||
print "Running %s.test02_DictionaryMethods..." % \
|
||||
self.__class__.__name__
|
||||
|
||||
for key in ['0002', '0101', '0401', '0701', '0998']:
|
||||
data = d[key]
|
||||
assert data == self.makeData(key)
|
||||
if verbose:
|
||||
print data
|
||||
|
||||
assert len(d) == self._numKeys
|
||||
keys = d.keys()
|
||||
assert len(keys) == self._numKeys
|
||||
assert type(keys) == type([])
|
||||
|
||||
d['new record'] = 'a new record'
|
||||
assert len(d) == self._numKeys+1
|
||||
keys = d.keys()
|
||||
assert len(keys) == self._numKeys+1
|
||||
|
||||
d['new record'] = 'a replacement record'
|
||||
assert len(d) == self._numKeys+1
|
||||
keys = d.keys()
|
||||
assert len(keys) == self._numKeys+1
|
||||
|
||||
if verbose:
|
||||
print "the first 10 keys are:"
|
||||
pprint(keys[:10])
|
||||
|
||||
assert d['new record'] == 'a replacement record'
|
||||
|
||||
assert d.has_key('0001') == 1
|
||||
assert d.has_key('spam') == 0
|
||||
|
||||
items = d.items()
|
||||
assert len(items) == self._numKeys+1
|
||||
assert type(items) == type([])
|
||||
assert type(items[0]) == type(())
|
||||
assert len(items[0]) == 2
|
||||
|
||||
if verbose:
|
||||
print "the first 10 items are:"
|
||||
pprint(items[:10])
|
||||
|
||||
values = d.values()
|
||||
assert len(values) == self._numKeys+1
|
||||
assert type(values) == type([])
|
||||
|
||||
if verbose:
|
||||
print "the first 10 values are:"
|
||||
pprint(values[:10])
|
||||
|
||||
|
||||
|
||||
#----------------------------------------
|
||||
|
||||
def test03_SimpleCursorStuff(self, get_raises_error=0, set_raises_error=0):
|
||||
if verbose:
|
||||
print '\n', '-=' * 30
|
||||
print "Running %s.test03_SimpleCursorStuff (get_error %s, set_error %s)..." % \
|
||||
(self.__class__.__name__, get_raises_error, set_raises_error)
|
||||
|
||||
if self.env and self.dbopenflags & db.DB_AUTO_COMMIT:
|
||||
txn = self.env.txn_begin()
|
||||
else:
|
||||
txn = None
|
||||
c = self.d.cursor(txn=txn)
|
||||
|
||||
rec = c.first()
|
||||
count = 0
|
||||
while rec is not None:
|
||||
count = count + 1
|
||||
if verbose and count % 100 == 0:
|
||||
print rec
|
||||
try:
|
||||
rec = c.next()
|
||||
except db.DBNotFoundError, val:
|
||||
if get_raises_error:
|
||||
assert val[0] == db.DB_NOTFOUND
|
||||
if verbose: print val
|
||||
rec = None
|
||||
else:
|
||||
self.fail("unexpected DBNotFoundError")
|
||||
assert c.get_current_size() == len(c.current()[1]), "%s != len(%r)" % (c.get_current_size(), c.current()[1])
|
||||
|
||||
assert count == self._numKeys
|
||||
|
||||
|
||||
rec = c.last()
|
||||
count = 0
|
||||
while rec is not None:
|
||||
count = count + 1
|
||||
if verbose and count % 100 == 0:
|
||||
print rec
|
||||
try:
|
||||
rec = c.prev()
|
||||
except db.DBNotFoundError, val:
|
||||
if get_raises_error:
|
||||
assert val[0] == db.DB_NOTFOUND
|
||||
if verbose: print val
|
||||
rec = None
|
||||
else:
|
||||
self.fail("unexpected DBNotFoundError")
|
||||
|
||||
assert count == self._numKeys
|
||||
|
||||
rec = c.set('0505')
|
||||
rec2 = c.current()
|
||||
assert rec == rec2
|
||||
assert rec[0] == '0505'
|
||||
assert rec[1] == self.makeData('0505')
|
||||
assert c.get_current_size() == len(rec[1])
|
||||
|
||||
# make sure we get empty values properly
|
||||
rec = c.set('empty value')
|
||||
assert rec[1] == ''
|
||||
assert c.get_current_size() == 0
|
||||
|
||||
try:
|
||||
n = c.set('bad key')
|
||||
except db.DBNotFoundError, val:
|
||||
assert val[0] == db.DB_NOTFOUND
|
||||
if verbose: print val
|
||||
else:
|
||||
if set_raises_error:
|
||||
self.fail("expected exception")
|
||||
if n != None:
|
||||
self.fail("expected None: %r" % (n,))
|
||||
|
||||
rec = c.get_both('0404', self.makeData('0404'))
|
||||
assert rec == ('0404', self.makeData('0404'))
|
||||
|
||||
try:
|
||||
n = c.get_both('0404', 'bad data')
|
||||
except db.DBNotFoundError, val:
|
||||
assert val[0] == db.DB_NOTFOUND
|
||||
if verbose: print val
|
||||
else:
|
||||
if get_raises_error:
|
||||
self.fail("expected exception")
|
||||
if n != None:
|
||||
self.fail("expected None: %r" % (n,))
|
||||
|
||||
if self.d.get_type() == db.DB_BTREE:
|
||||
rec = c.set_range('011')
|
||||
if verbose:
|
||||
print "searched for '011', found: ", rec
|
||||
|
||||
rec = c.set_range('011',dlen=0,doff=0)
|
||||
if verbose:
|
||||
print "searched (partial) for '011', found: ", rec
|
||||
if rec[1] != '': self.fail('expected empty data portion')
|
||||
|
||||
ev = c.set_range('empty value')
|
||||
if verbose:
|
||||
print "search for 'empty value' returned", ev
|
||||
if ev[1] != '': self.fail('empty value lookup failed')
|
||||
|
||||
c.set('0499')
|
||||
c.delete()
|
||||
try:
|
||||
rec = c.current()
|
||||
except db.DBKeyEmptyError, val:
|
||||
if get_raises_error:
|
||||
assert val[0] == db.DB_KEYEMPTY
|
||||
if verbose: print val
|
||||
else:
|
||||
self.fail("unexpected DBKeyEmptyError")
|
||||
else:
|
||||
if get_raises_error:
|
||||
self.fail('DBKeyEmptyError exception expected')
|
||||
|
||||
c.next()
|
||||
c2 = c.dup(db.DB_POSITION)
|
||||
assert c.current() == c2.current()
|
||||
|
||||
c2.put('', 'a new value', db.DB_CURRENT)
|
||||
assert c.current() == c2.current()
|
||||
assert c.current()[1] == 'a new value'
|
||||
|
||||
c2.put('', 'er', db.DB_CURRENT, dlen=0, doff=5)
|
||||
assert c2.current()[1] == 'a newer value'
|
||||
|
||||
c.close()
|
||||
c2.close()
|
||||
if txn:
|
||||
txn.commit()
|
||||
|
||||
# time to abuse the closed cursors and hope we don't crash
|
||||
methods_to_test = {
|
||||
'current': (),
|
||||
'delete': (),
|
||||
'dup': (db.DB_POSITION,),
|
||||
'first': (),
|
||||
'get': (0,),
|
||||
'next': (),
|
||||
'prev': (),
|
||||
'last': (),
|
||||
'put':('', 'spam', db.DB_CURRENT),
|
||||
'set': ("0505",),
|
||||
}
|
||||
for method, args in methods_to_test.items():
|
||||
try:
|
||||
if verbose:
|
||||
print "attempting to use a closed cursor's %s method" % \
|
||||
method
|
||||
# a bug may cause a NULL pointer dereference...
|
||||
apply(getattr(c, method), args)
|
||||
except db.DBError, val:
|
||||
assert val[0] == 0
|
||||
if verbose: print val
|
||||
else:
|
||||
self.fail("no exception raised when using a buggy cursor's"
|
||||
"%s method" % method)
|
||||
|
||||
#
|
||||
# free cursor referencing a closed database, it should not barf:
|
||||
#
|
||||
oldcursor = self.d.cursor(txn=txn)
|
||||
self.d.close()
|
||||
|
||||
# this would originally cause a segfault when the cursor for a
|
||||
# closed database was cleaned up. it should not anymore.
|
||||
# SF pybsddb bug id 667343
|
||||
del oldcursor
|
||||
|
||||
def test03b_SimpleCursorWithoutGetReturnsNone0(self):
|
||||
# same test but raise exceptions instead of returning None
|
||||
if verbose:
|
||||
print '\n', '-=' * 30
|
||||
print "Running %s.test03b_SimpleCursorStuffWithoutGetReturnsNone..." % \
|
||||
self.__class__.__name__
|
||||
|
||||
old = self.d.set_get_returns_none(0)
|
||||
assert old == 2
|
||||
self.test03_SimpleCursorStuff(get_raises_error=1, set_raises_error=1)
|
||||
|
||||
def test03b_SimpleCursorWithGetReturnsNone1(self):
|
||||
# same test but raise exceptions instead of returning None
|
||||
if verbose:
|
||||
print '\n', '-=' * 30
|
||||
print "Running %s.test03b_SimpleCursorStuffWithoutGetReturnsNone..." % \
|
||||
self.__class__.__name__
|
||||
|
||||
old = self.d.set_get_returns_none(1)
|
||||
self.test03_SimpleCursorStuff(get_raises_error=0, set_raises_error=1)
|
||||
|
||||
|
||||
def test03c_SimpleCursorGetReturnsNone2(self):
|
||||
# same test but raise exceptions instead of returning None
|
||||
if verbose:
|
||||
print '\n', '-=' * 30
|
||||
print "Running %s.test03c_SimpleCursorStuffWithoutSetReturnsNone..." % \
|
||||
self.__class__.__name__
|
||||
|
||||
old = self.d.set_get_returns_none(1)
|
||||
assert old == 2
|
||||
old = self.d.set_get_returns_none(2)
|
||||
assert old == 1
|
||||
self.test03_SimpleCursorStuff(get_raises_error=0, set_raises_error=0)
|
||||
|
||||
#----------------------------------------
|
||||
|
||||
def test04_PartialGetAndPut(self):
|
||||
d = self.d
|
||||
if verbose:
|
||||
print '\n', '-=' * 30
|
||||
print "Running %s.test04_PartialGetAndPut..." % \
|
||||
self.__class__.__name__
|
||||
|
||||
key = "partialTest"
|
||||
data = "1" * 1000 + "2" * 1000
|
||||
d.put(key, data)
|
||||
assert d.get(key) == data
|
||||
assert d.get(key, dlen=20, doff=990) == ("1" * 10) + ("2" * 10)
|
||||
|
||||
d.put("partialtest2", ("1" * 30000) + "robin" )
|
||||
assert d.get("partialtest2", dlen=5, doff=30000) == "robin"
|
||||
|
||||
# There seems to be a bug in DB here... Commented out the test for
|
||||
# now.
|
||||
##assert d.get("partialtest2", dlen=5, doff=30010) == ""
|
||||
|
||||
if self.dbsetflags != db.DB_DUP:
|
||||
# Partial put with duplicate records requires a cursor
|
||||
d.put(key, "0000", dlen=2000, doff=0)
|
||||
assert d.get(key) == "0000"
|
||||
|
||||
d.put(key, "1111", dlen=1, doff=2)
|
||||
assert d.get(key) == "0011110"
|
||||
|
||||
#----------------------------------------
|
||||
|
||||
def test05_GetSize(self):
|
||||
d = self.d
|
||||
if verbose:
|
||||
print '\n', '-=' * 30
|
||||
print "Running %s.test05_GetSize..." % self.__class__.__name__
|
||||
|
||||
for i in range(1, 50000, 500):
|
||||
key = "size%s" % i
|
||||
#print "before ", i,
|
||||
d.put(key, "1" * i)
|
||||
#print "after",
|
||||
assert d.get_size(key) == i
|
||||
#print "done"
|
||||
|
||||
#----------------------------------------
|
||||
|
||||
def test06_Truncate(self):
|
||||
if db.version() < (3,3):
|
||||
# truncate is a feature of BerkeleyDB 3.3 and above
|
||||
return
|
||||
|
||||
d = self.d
|
||||
if verbose:
|
||||
print '\n', '-=' * 30
|
||||
print "Running %s.test99_Truncate..." % self.__class__.__name__
|
||||
|
||||
d.put("abcde", "ABCDE");
|
||||
num = d.truncate()
|
||||
assert num >= 1, "truncate returned <= 0 on non-empty database"
|
||||
num = d.truncate()
|
||||
assert num == 0, "truncate on empty DB returned nonzero (%r)" % (num,)
|
||||
|
||||
#----------------------------------------
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
|
||||
class BasicBTreeTestCase(BasicTestCase):
|
||||
dbtype = db.DB_BTREE
|
||||
|
||||
|
||||
class BasicHashTestCase(BasicTestCase):
|
||||
dbtype = db.DB_HASH
|
||||
|
||||
|
||||
class BasicBTreeWithThreadFlagTestCase(BasicTestCase):
|
||||
dbtype = db.DB_BTREE
|
||||
dbopenflags = db.DB_THREAD
|
||||
|
||||
|
||||
class BasicHashWithThreadFlagTestCase(BasicTestCase):
|
||||
dbtype = db.DB_HASH
|
||||
dbopenflags = db.DB_THREAD
|
||||
|
||||
|
||||
class BasicWithEnvTestCase(BasicTestCase):
|
||||
dbopenflags = db.DB_THREAD
|
||||
useEnv = 1
|
||||
envflags = db.DB_THREAD | db.DB_INIT_MPOOL | db.DB_INIT_LOCK
|
||||
|
||||
#----------------------------------------
|
||||
|
||||
def test07_EnvRemoveAndRename(self):
|
||||
if not self.env:
|
||||
return
|
||||
|
||||
if verbose:
|
||||
print '\n', '-=' * 30
|
||||
print "Running %s.test07_EnvRemoveAndRename..." % self.__class__.__name__
|
||||
|
||||
# can't rename or remove an open DB
|
||||
self.d.close()
|
||||
|
||||
newname = self.filename + '.renamed'
|
||||
self.env.dbrename(self.filename, None, newname)
|
||||
self.env.dbremove(newname)
|
||||
|
||||
# dbremove and dbrename are in 4.1 and later
|
||||
if db.version() < (4,1):
|
||||
del test07_EnvRemoveAndRename
|
||||
|
||||
#----------------------------------------
|
||||
|
||||
class BasicBTreeWithEnvTestCase(BasicWithEnvTestCase):
|
||||
dbtype = db.DB_BTREE
|
||||
|
||||
|
||||
class BasicHashWithEnvTestCase(BasicWithEnvTestCase):
|
||||
dbtype = db.DB_HASH
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
class BasicTransactionTestCase(BasicTestCase):
|
||||
dbopenflags = db.DB_THREAD | db.DB_AUTO_COMMIT
|
||||
useEnv = 1
|
||||
envflags = (db.DB_THREAD | db.DB_INIT_MPOOL | db.DB_INIT_LOCK |
|
||||
db.DB_INIT_TXN)
|
||||
envsetflags = db.DB_AUTO_COMMIT
|
||||
|
||||
|
||||
def tearDown(self):
|
||||
self.txn.commit()
|
||||
BasicTestCase.tearDown(self)
|
||||
|
||||
|
||||
def populateDB(self):
|
||||
txn = self.env.txn_begin()
|
||||
BasicTestCase.populateDB(self, _txn=txn)
|
||||
|
||||
self.txn = self.env.txn_begin()
|
||||
|
||||
|
||||
def test06_Transactions(self):
|
||||
d = self.d
|
||||
if verbose:
|
||||
print '\n', '-=' * 30
|
||||
print "Running %s.test06_Transactions..." % self.__class__.__name__
|
||||
|
||||
assert d.get('new rec', txn=self.txn) == None
|
||||
d.put('new rec', 'this is a new record', self.txn)
|
||||
assert d.get('new rec', txn=self.txn) == 'this is a new record'
|
||||
self.txn.abort()
|
||||
assert d.get('new rec') == None
|
||||
|
||||
self.txn = self.env.txn_begin()
|
||||
|
||||
assert d.get('new rec', txn=self.txn) == None
|
||||
d.put('new rec', 'this is a new record', self.txn)
|
||||
assert d.get('new rec', txn=self.txn) == 'this is a new record'
|
||||
self.txn.commit()
|
||||
assert d.get('new rec') == 'this is a new record'
|
||||
|
||||
self.txn = self.env.txn_begin()
|
||||
c = d.cursor(self.txn)
|
||||
rec = c.first()
|
||||
count = 0
|
||||
while rec is not None:
|
||||
count = count + 1
|
||||
if verbose and count % 100 == 0:
|
||||
print rec
|
||||
rec = c.next()
|
||||
assert count == self._numKeys+1
|
||||
|
||||
c.close() # Cursors *MUST* be closed before commit!
|
||||
self.txn.commit()
|
||||
|
||||
# flush pending updates
|
||||
try:
|
||||
self.env.txn_checkpoint (0, 0, 0)
|
||||
except db.DBIncompleteError:
|
||||
pass
|
||||
|
||||
if db.version() >= (4,0):
|
||||
statDict = self.env.log_stat(0);
|
||||
assert statDict.has_key('magic')
|
||||
assert statDict.has_key('version')
|
||||
assert statDict.has_key('cur_file')
|
||||
assert statDict.has_key('region_nowait')
|
||||
|
||||
# must have at least one log file present:
|
||||
logs = self.env.log_archive(db.DB_ARCH_ABS | db.DB_ARCH_LOG)
|
||||
assert logs != None
|
||||
for log in logs:
|
||||
if verbose:
|
||||
print 'log file: ' + log
|
||||
if db.version() >= (4,2):
|
||||
logs = self.env.log_archive(db.DB_ARCH_REMOVE)
|
||||
assert not logs
|
||||
|
||||
self.txn = self.env.txn_begin()
|
||||
|
||||
#----------------------------------------
|
||||
|
||||
def test07_TxnTruncate(self):
|
||||
if db.version() < (3,3):
|
||||
# truncate is a feature of BerkeleyDB 3.3 and above
|
||||
return
|
||||
|
||||
d = self.d
|
||||
if verbose:
|
||||
print '\n', '-=' * 30
|
||||
print "Running %s.test07_TxnTruncate..." % self.__class__.__name__
|
||||
|
||||
d.put("abcde", "ABCDE");
|
||||
txn = self.env.txn_begin()
|
||||
num = d.truncate(txn)
|
||||
assert num >= 1, "truncate returned <= 0 on non-empty database"
|
||||
num = d.truncate(txn)
|
||||
assert num == 0, "truncate on empty DB returned nonzero (%r)" % (num,)
|
||||
txn.commit()
|
||||
|
||||
#----------------------------------------
|
||||
|
||||
def test08_TxnLateUse(self):
|
||||
txn = self.env.txn_begin()
|
||||
txn.abort()
|
||||
try:
|
||||
txn.abort()
|
||||
except db.DBError, e:
|
||||
pass
|
||||
else:
|
||||
raise RuntimeError, "DBTxn.abort() called after DB_TXN no longer valid w/o an exception"
|
||||
|
||||
txn = self.env.txn_begin()
|
||||
txn.commit()
|
||||
try:
|
||||
txn.commit()
|
||||
except db.DBError, e:
|
||||
pass
|
||||
else:
|
||||
raise RuntimeError, "DBTxn.commit() called after DB_TXN no longer valid w/o an exception"
|
||||
|
||||
|
||||
class BTreeTransactionTestCase(BasicTransactionTestCase):
|
||||
dbtype = db.DB_BTREE
|
||||
|
||||
class HashTransactionTestCase(BasicTransactionTestCase):
|
||||
dbtype = db.DB_HASH
|
||||
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
class BTreeRecnoTestCase(BasicTestCase):
|
||||
dbtype = db.DB_BTREE
|
||||
dbsetflags = db.DB_RECNUM
|
||||
|
||||
def test07_RecnoInBTree(self):
|
||||
d = self.d
|
||||
if verbose:
|
||||
print '\n', '-=' * 30
|
||||
print "Running %s.test07_RecnoInBTree..." % self.__class__.__name__
|
||||
|
||||
rec = d.get(200)
|
||||
assert type(rec) == type(())
|
||||
assert len(rec) == 2
|
||||
if verbose:
|
||||
print "Record #200 is ", rec
|
||||
|
||||
c = d.cursor()
|
||||
c.set('0200')
|
||||
num = c.get_recno()
|
||||
assert type(num) == type(1)
|
||||
if verbose:
|
||||
print "recno of d['0200'] is ", num
|
||||
|
||||
rec = c.current()
|
||||
assert c.set_recno(num) == rec
|
||||
|
||||
c.close()
|
||||
|
||||
|
||||
|
||||
class BTreeRecnoWithThreadFlagTestCase(BTreeRecnoTestCase):
|
||||
dbopenflags = db.DB_THREAD
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
class BasicDUPTestCase(BasicTestCase):
|
||||
dbsetflags = db.DB_DUP
|
||||
|
||||
def test08_DuplicateKeys(self):
|
||||
d = self.d
|
||||
if verbose:
|
||||
print '\n', '-=' * 30
|
||||
print "Running %s.test08_DuplicateKeys..." % \
|
||||
self.__class__.__name__
|
||||
|
||||
d.put("dup0", "before")
|
||||
for x in "The quick brown fox jumped over the lazy dog.".split():
|
||||
d.put("dup1", x)
|
||||
d.put("dup2", "after")
|
||||
|
||||
data = d.get("dup1")
|
||||
assert data == "The"
|
||||
if verbose:
|
||||
print data
|
||||
|
||||
c = d.cursor()
|
||||
rec = c.set("dup1")
|
||||
assert rec == ('dup1', 'The')
|
||||
|
||||
next = c.next()
|
||||
assert next == ('dup1', 'quick')
|
||||
|
||||
rec = c.set("dup1")
|
||||
count = c.count()
|
||||
assert count == 9
|
||||
|
||||
next_dup = c.next_dup()
|
||||
assert next_dup == ('dup1', 'quick')
|
||||
|
||||
rec = c.set('dup1')
|
||||
while rec is not None:
|
||||
if verbose:
|
||||
print rec
|
||||
rec = c.next_dup()
|
||||
|
||||
c.set('dup1')
|
||||
rec = c.next_nodup()
|
||||
assert rec[0] != 'dup1'
|
||||
if verbose:
|
||||
print rec
|
||||
|
||||
c.close()
|
||||
|
||||
|
||||
|
||||
class BTreeDUPTestCase(BasicDUPTestCase):
|
||||
dbtype = db.DB_BTREE
|
||||
|
||||
class HashDUPTestCase(BasicDUPTestCase):
|
||||
dbtype = db.DB_HASH
|
||||
|
||||
class BTreeDUPWithThreadTestCase(BasicDUPTestCase):
|
||||
dbtype = db.DB_BTREE
|
||||
dbopenflags = db.DB_THREAD
|
||||
|
||||
class HashDUPWithThreadTestCase(BasicDUPTestCase):
|
||||
dbtype = db.DB_HASH
|
||||
dbopenflags = db.DB_THREAD
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
class BasicMultiDBTestCase(BasicTestCase):
|
||||
dbname = 'first'
|
||||
|
||||
def otherType(self):
|
||||
if self.dbtype == db.DB_BTREE:
|
||||
return db.DB_HASH
|
||||
else:
|
||||
return db.DB_BTREE
|
||||
|
||||
def test09_MultiDB(self):
|
||||
d1 = self.d
|
||||
if verbose:
|
||||
print '\n', '-=' * 30
|
||||
print "Running %s.test09_MultiDB..." % self.__class__.__name__
|
||||
|
||||
d2 = db.DB(self.env)
|
||||
d2.open(self.filename, "second", self.dbtype,
|
||||
self.dbopenflags|db.DB_CREATE)
|
||||
d3 = db.DB(self.env)
|
||||
d3.open(self.filename, "third", self.otherType(),
|
||||
self.dbopenflags|db.DB_CREATE)
|
||||
|
||||
for x in "The quick brown fox jumped over the lazy dog".split():
|
||||
d2.put(x, self.makeData(x))
|
||||
|
||||
for x in string.letters:
|
||||
d3.put(x, x*70)
|
||||
|
||||
d1.sync()
|
||||
d2.sync()
|
||||
d3.sync()
|
||||
d1.close()
|
||||
d2.close()
|
||||
d3.close()
|
||||
|
||||
self.d = d1 = d2 = d3 = None
|
||||
|
||||
self.d = d1 = db.DB(self.env)
|
||||
d1.open(self.filename, self.dbname, flags = self.dbopenflags)
|
||||
d2 = db.DB(self.env)
|
||||
d2.open(self.filename, "second", flags = self.dbopenflags)
|
||||
d3 = db.DB(self.env)
|
||||
d3.open(self.filename, "third", flags = self.dbopenflags)
|
||||
|
||||
c1 = d1.cursor()
|
||||
c2 = d2.cursor()
|
||||
c3 = d3.cursor()
|
||||
|
||||
count = 0
|
||||
rec = c1.first()
|
||||
while rec is not None:
|
||||
count = count + 1
|
||||
if verbose and (count % 50) == 0:
|
||||
print rec
|
||||
rec = c1.next()
|
||||
assert count == self._numKeys
|
||||
|
||||
count = 0
|
||||
rec = c2.first()
|
||||
while rec is not None:
|
||||
count = count + 1
|
||||
if verbose:
|
||||
print rec
|
||||
rec = c2.next()
|
||||
assert count == 9
|
||||
|
||||
count = 0
|
||||
rec = c3.first()
|
||||
while rec is not None:
|
||||
count = count + 1
|
||||
if verbose:
|
||||
print rec
|
||||
rec = c3.next()
|
||||
assert count == 52
|
||||
|
||||
|
||||
c1.close()
|
||||
c2.close()
|
||||
c3.close()
|
||||
|
||||
d2.close()
|
||||
d3.close()
|
||||
|
||||
|
||||
|
||||
# Strange things happen if you try to use Multiple DBs per file without a
|
||||
# DBEnv with MPOOL and LOCKing...
|
||||
|
||||
class BTreeMultiDBTestCase(BasicMultiDBTestCase):
|
||||
dbtype = db.DB_BTREE
|
||||
dbopenflags = db.DB_THREAD
|
||||
useEnv = 1
|
||||
envflags = db.DB_THREAD | db.DB_INIT_MPOOL | db.DB_INIT_LOCK
|
||||
|
||||
class HashMultiDBTestCase(BasicMultiDBTestCase):
|
||||
dbtype = db.DB_HASH
|
||||
dbopenflags = db.DB_THREAD
|
||||
useEnv = 1
|
||||
envflags = db.DB_THREAD | db.DB_INIT_MPOOL | db.DB_INIT_LOCK
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
def test_suite():
|
||||
suite = unittest.TestSuite()
|
||||
|
||||
suite.addTest(unittest.makeSuite(VersionTestCase))
|
||||
suite.addTest(unittest.makeSuite(BasicBTreeTestCase))
|
||||
suite.addTest(unittest.makeSuite(BasicHashTestCase))
|
||||
suite.addTest(unittest.makeSuite(BasicBTreeWithThreadFlagTestCase))
|
||||
suite.addTest(unittest.makeSuite(BasicHashWithThreadFlagTestCase))
|
||||
suite.addTest(unittest.makeSuite(BasicBTreeWithEnvTestCase))
|
||||
suite.addTest(unittest.makeSuite(BasicHashWithEnvTestCase))
|
||||
suite.addTest(unittest.makeSuite(BTreeTransactionTestCase))
|
||||
suite.addTest(unittest.makeSuite(HashTransactionTestCase))
|
||||
suite.addTest(unittest.makeSuite(BTreeRecnoTestCase))
|
||||
suite.addTest(unittest.makeSuite(BTreeRecnoWithThreadFlagTestCase))
|
||||
suite.addTest(unittest.makeSuite(BTreeDUPTestCase))
|
||||
suite.addTest(unittest.makeSuite(HashDUPTestCase))
|
||||
suite.addTest(unittest.makeSuite(BTreeDUPWithThreadTestCase))
|
||||
suite.addTest(unittest.makeSuite(HashDUPWithThreadTestCase))
|
||||
suite.addTest(unittest.makeSuite(BTreeMultiDBTestCase))
|
||||
suite.addTest(unittest.makeSuite(HashMultiDBTestCase))
|
||||
|
||||
return suite
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(defaultTest='test_suite')
|
|
@ -1,249 +0,0 @@
|
|||
"""
|
||||
TestCases for python DB Btree key comparison function.
|
||||
"""
|
||||
|
||||
import sys, os, re
|
||||
import test_all
|
||||
from cStringIO import StringIO
|
||||
|
||||
import unittest
|
||||
try:
|
||||
# For Pythons w/distutils pybsddb
|
||||
from bsddb3 import db, dbshelve
|
||||
except ImportError:
|
||||
# For Python 2.3
|
||||
from bsddb import db, dbshelve
|
||||
|
||||
lexical_cmp = cmp
|
||||
|
||||
def lowercase_cmp(left, right):
|
||||
return cmp (left.lower(), right.lower())
|
||||
|
||||
def make_reverse_comparator (cmp):
|
||||
def reverse (left, right, delegate=cmp):
|
||||
return - delegate (left, right)
|
||||
return reverse
|
||||
|
||||
_expected_lexical_test_data = ['', 'CCCP', 'a', 'aaa', 'b', 'c', 'cccce', 'ccccf']
|
||||
_expected_lowercase_test_data = ['', 'a', 'aaa', 'b', 'c', 'CC', 'cccce', 'ccccf', 'CCCP']
|
||||
|
||||
class ComparatorTests (unittest.TestCase):
|
||||
def comparator_test_helper (self, comparator, expected_data):
|
||||
data = expected_data[:]
|
||||
data.sort (comparator)
|
||||
self.failUnless (data == expected_data,
|
||||
"comparator `%s' is not right: %s vs. %s"
|
||||
% (comparator, expected_data, data))
|
||||
def test_lexical_comparator (self):
|
||||
self.comparator_test_helper (lexical_cmp, _expected_lexical_test_data)
|
||||
def test_reverse_lexical_comparator (self):
|
||||
rev = _expected_lexical_test_data[:]
|
||||
rev.reverse ()
|
||||
self.comparator_test_helper (make_reverse_comparator (lexical_cmp),
|
||||
rev)
|
||||
def test_lowercase_comparator (self):
|
||||
self.comparator_test_helper (lowercase_cmp,
|
||||
_expected_lowercase_test_data)
|
||||
|
||||
class AbstractBtreeKeyCompareTestCase (unittest.TestCase):
|
||||
env = None
|
||||
db = None
|
||||
|
||||
def setUp (self):
|
||||
self.filename = self.__class__.__name__ + '.db'
|
||||
homeDir = os.path.join (os.path.dirname (sys.argv[0]), 'db_home')
|
||||
self.homeDir = homeDir
|
||||
try:
|
||||
os.mkdir (homeDir)
|
||||
except os.error:
|
||||
pass
|
||||
|
||||
env = db.DBEnv ()
|
||||
env.open (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
|
||||
import glob
|
||||
map (os.remove, glob.glob (os.path.join (self.homeDir, '*')))
|
||||
|
||||
def addDataToDB (self, data):
|
||||
i = 0
|
||||
for item in data:
|
||||
self.db.put (item, str (i))
|
||||
i = i + 1
|
||||
|
||||
def createDB (self, key_comparator):
|
||||
self.db = db.DB (self.env)
|
||||
self.setupDB (key_comparator)
|
||||
self.db.open (self.filename, "test", db.DB_BTREE, db.DB_CREATE)
|
||||
|
||||
def setupDB (self, key_comparator):
|
||||
self.db.set_bt_compare (key_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:
|
||||
key, ignore = rec
|
||||
self.failUnless (index < len (expected),
|
||||
"to many values returned from cursor")
|
||||
self.failUnless (expected[index] == key,
|
||||
"expected value `%s' at %d but got `%s'"
|
||||
% (expected[index], index, key))
|
||||
index = index + 1
|
||||
rec = curs.next ()
|
||||
self.failUnless (index == len (expected),
|
||||
"not enough values returned from cursor")
|
||||
finally:
|
||||
curs.close ()
|
||||
|
||||
class BtreeKeyCompareTestCase (AbstractBtreeKeyCompareTestCase):
|
||||
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)
|
||||
|
||||
def test_compare_function_useless (self):
|
||||
self.startTest ()
|
||||
def socialist_comparator (l, r):
|
||||
return 0
|
||||
self.createDB (socialist_comparator)
|
||||
self.addDataToDB (['b', 'a', 'd'])
|
||||
# all things being equal the first key will be the only key
|
||||
# in the database... (with the last key's value fwiw)
|
||||
self.finishTest (['b'])
|
||||
|
||||
|
||||
class BtreeExceptionsTestCase (AbstractBtreeKeyCompareTestCase):
|
||||
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_bt_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_bt_compare checks that comparator('', '') == 0
|
||||
self.assertRaises (TypeError, self.createDB, bad_comparator)
|
||||
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)
|
||||
|
||||
def _test_compare_function_exception (self):
|
||||
self.startTest ()
|
||||
def bad_comparator (l, r):
|
||||
if l == r:
|
||||
# pass the set_bt_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_bt_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)
|
||||
try:
|
||||
self.db.set_bt_compare (my_compare)
|
||||
assert False, "this set should fail"
|
||||
|
||||
except RuntimeError, msg:
|
||||
pass
|
||||
|
||||
def test_suite ():
|
||||
res = unittest.TestSuite ()
|
||||
|
||||
res.addTest (unittest.makeSuite (ComparatorTests))
|
||||
if db.version () >= (3, 3, 11):
|
||||
res.addTest (unittest.makeSuite (BtreeExceptionsTestCase))
|
||||
res.addTest (unittest.makeSuite (BtreeKeyCompareTestCase))
|
||||
return res
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main (defaultTest = 'suite')
|
|
@ -1,191 +0,0 @@
|
|||
"""
|
||||
Test cases adapted from the test_bsddb.py module in Python's
|
||||
regression test suite.
|
||||
"""
|
||||
|
||||
import sys, os, string
|
||||
import unittest
|
||||
import tempfile
|
||||
|
||||
from test_all import verbose
|
||||
|
||||
try:
|
||||
# For Pythons w/distutils pybsddb
|
||||
from bsddb3 import db, hashopen, btopen, rnopen
|
||||
except ImportError:
|
||||
# For Python 2.3
|
||||
from bsddb import db, hashopen, btopen, rnopen
|
||||
|
||||
|
||||
class CompatibilityTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.filename = tempfile.mktemp()
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
os.remove(self.filename)
|
||||
except os.error:
|
||||
pass
|
||||
|
||||
|
||||
def test01_btopen(self):
|
||||
self.do_bthash_test(btopen, 'btopen')
|
||||
|
||||
def test02_hashopen(self):
|
||||
self.do_bthash_test(hashopen, 'hashopen')
|
||||
|
||||
def test03_rnopen(self):
|
||||
data = string.split("The quick brown fox jumped over the lazy dog.")
|
||||
if verbose:
|
||||
print "\nTesting: rnopen"
|
||||
|
||||
f = rnopen(self.filename, 'c')
|
||||
for x in range(len(data)):
|
||||
f[x+1] = data[x]
|
||||
|
||||
getTest = (f[1], f[2], f[3])
|
||||
if verbose:
|
||||
print '%s %s %s' % getTest
|
||||
|
||||
assert getTest[1] == 'quick', 'data mismatch!'
|
||||
|
||||
rv = f.set_location(3)
|
||||
if rv != (3, 'brown'):
|
||||
self.fail('recno database set_location failed: '+repr(rv))
|
||||
|
||||
f[25] = 'twenty-five'
|
||||
f.close()
|
||||
del f
|
||||
|
||||
f = rnopen(self.filename, 'w')
|
||||
f[20] = 'twenty'
|
||||
|
||||
def noRec(f):
|
||||
rec = f[15]
|
||||
self.assertRaises(KeyError, noRec, f)
|
||||
|
||||
def badKey(f):
|
||||
rec = f['a string']
|
||||
self.assertRaises(TypeError, badKey, f)
|
||||
|
||||
del f[3]
|
||||
|
||||
rec = f.first()
|
||||
while rec:
|
||||
if verbose:
|
||||
print rec
|
||||
try:
|
||||
rec = f.next()
|
||||
except KeyError:
|
||||
break
|
||||
|
||||
f.close()
|
||||
|
||||
|
||||
def test04_n_flag(self):
|
||||
f = hashopen(self.filename, 'n')
|
||||
f.close()
|
||||
|
||||
|
||||
def do_bthash_test(self, factory, what):
|
||||
if verbose:
|
||||
print '\nTesting: ', what
|
||||
|
||||
f = factory(self.filename, 'c')
|
||||
if verbose:
|
||||
print 'creation...'
|
||||
|
||||
# truth test
|
||||
if f:
|
||||
if verbose: print "truth test: true"
|
||||
else:
|
||||
if verbose: print "truth test: false"
|
||||
|
||||
f['0'] = ''
|
||||
f['a'] = 'Guido'
|
||||
f['b'] = 'van'
|
||||
f['c'] = 'Rossum'
|
||||
f['d'] = 'invented'
|
||||
# 'e' intentionally left out
|
||||
f['f'] = 'Python'
|
||||
if verbose:
|
||||
print '%s %s %s' % (f['a'], f['b'], f['c'])
|
||||
|
||||
if verbose:
|
||||
print 'key ordering...'
|
||||
start = f.set_location(f.first()[0])
|
||||
if start != ('0', ''):
|
||||
self.fail("incorrect first() result: "+repr(start))
|
||||
while 1:
|
||||
try:
|
||||
rec = f.next()
|
||||
except KeyError:
|
||||
assert rec == f.last(), 'Error, last <> last!'
|
||||
f.previous()
|
||||
break
|
||||
if verbose:
|
||||
print rec
|
||||
|
||||
assert f.has_key('f'), 'Error, missing key!'
|
||||
|
||||
# test that set_location() returns the next nearest key, value
|
||||
# on btree databases and raises KeyError on others.
|
||||
if factory == btopen:
|
||||
e = f.set_location('e')
|
||||
if e != ('f', 'Python'):
|
||||
self.fail('wrong key,value returned: '+repr(e))
|
||||
else:
|
||||
try:
|
||||
e = f.set_location('e')
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
self.fail("set_location on non-existant key did not raise KeyError")
|
||||
|
||||
f.sync()
|
||||
f.close()
|
||||
# truth test
|
||||
try:
|
||||
if f:
|
||||
if verbose: print "truth test: true"
|
||||
else:
|
||||
if verbose: print "truth test: false"
|
||||
except db.DBError:
|
||||
pass
|
||||
else:
|
||||
self.fail("Exception expected")
|
||||
|
||||
del f
|
||||
|
||||
if verbose:
|
||||
print 'modification...'
|
||||
f = factory(self.filename, 'w')
|
||||
f['d'] = 'discovered'
|
||||
|
||||
if verbose:
|
||||
print 'access...'
|
||||
for key in f.keys():
|
||||
word = f[key]
|
||||
if verbose:
|
||||
print word
|
||||
|
||||
def noRec(f):
|
||||
rec = f['no such key']
|
||||
self.assertRaises(KeyError, noRec, f)
|
||||
|
||||
def badKey(f):
|
||||
rec = f[15]
|
||||
self.assertRaises(TypeError, badKey, f)
|
||||
|
||||
f.close()
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
|
||||
def test_suite():
|
||||
return unittest.makeSuite(CompatibilityTestCase)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(defaultTest='test_suite')
|
|
@ -1,65 +0,0 @@
|
|||
import unittest
|
||||
import sys, os, glob
|
||||
|
||||
try:
|
||||
# For Pythons w/distutils pybsddb
|
||||
from bsddb3 import db
|
||||
except ImportError:
|
||||
# For Python 2.3
|
||||
from bsddb import db
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
class pget_bugTestCase(unittest.TestCase):
|
||||
"""Verify that cursor.pget works properly"""
|
||||
db_name = 'test-cursor_pget.db'
|
||||
|
||||
def setUp(self):
|
||||
self.homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
|
||||
try:
|
||||
os.mkdir(self.homeDir)
|
||||
except os.error:
|
||||
pass
|
||||
self.env = db.DBEnv()
|
||||
self.env.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL)
|
||||
self.primary_db = db.DB(self.env)
|
||||
self.primary_db.open(self.db_name, 'primary', db.DB_BTREE, db.DB_CREATE)
|
||||
self.secondary_db = db.DB(self.env)
|
||||
self.secondary_db.set_flags(db.DB_DUP)
|
||||
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.put('salad', 'eggs')
|
||||
self.primary_db.put('spam', 'ham')
|
||||
self.primary_db.put('omelet', 'eggs')
|
||||
|
||||
|
||||
def tearDown(self):
|
||||
self.secondary_db.close()
|
||||
self.primary_db.close()
|
||||
self.env.close()
|
||||
del self.secondary_db
|
||||
del self.primary_db
|
||||
del self.env
|
||||
for file in glob.glob(os.path.join(self.homeDir, '*')):
|
||||
os.remove(file)
|
||||
os.removedirs(self.homeDir)
|
||||
|
||||
def test_pget(self):
|
||||
cursor = self.secondary_db.cursor()
|
||||
|
||||
self.assertEquals(('eggs', 'salad', 'eggs'), cursor.pget(key='eggs', flags=db.DB_SET))
|
||||
self.assertEquals(('eggs', 'omelet', 'eggs'), cursor.pget(db.DB_NEXT_DUP))
|
||||
self.assertEquals(None, cursor.pget(db.DB_NEXT_DUP))
|
||||
|
||||
self.assertEquals(('ham', 'spam', 'ham'), cursor.pget('ham', 'spam', flags=db.DB_SET))
|
||||
self.assertEquals(None, cursor.pget(db.DB_NEXT_DUP))
|
||||
|
||||
cursor.close()
|
||||
|
||||
|
||||
def test_suite():
|
||||
return unittest.makeSuite(pget_bugTestCase)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(defaultTest='test_suite')
|
|
@ -1,82 +0,0 @@
|
|||
|
||||
import sys, os, string
|
||||
import unittest
|
||||
import glob
|
||||
|
||||
try:
|
||||
# For Pythons w/distutils pybsddb
|
||||
from bsddb3 import db, dbobj
|
||||
except ImportError:
|
||||
# For Python 2.3
|
||||
from bsddb import db, dbobj
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
class dbobjTestCase(unittest.TestCase):
|
||||
"""Verify that dbobj.DB and dbobj.DBEnv work properly"""
|
||||
db_home = 'db_home'
|
||||
db_name = 'test-dbobj.db'
|
||||
|
||||
def setUp(self):
|
||||
homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
|
||||
self.homeDir = homeDir
|
||||
try: os.mkdir(homeDir)
|
||||
except os.error: pass
|
||||
|
||||
def tearDown(self):
|
||||
if hasattr(self, 'db'):
|
||||
del self.db
|
||||
if hasattr(self, 'env'):
|
||||
del self.env
|
||||
files = glob.glob(os.path.join(self.homeDir, '*'))
|
||||
for file in files:
|
||||
os.remove(file)
|
||||
|
||||
def test01_both(self):
|
||||
class TestDBEnv(dbobj.DBEnv): pass
|
||||
class TestDB(dbobj.DB):
|
||||
def put(self, key, *args, **kwargs):
|
||||
key = string.upper(key)
|
||||
# call our parent classes put method with an upper case key
|
||||
return apply(dbobj.DB.put, (self, key) + args, kwargs)
|
||||
self.env = TestDBEnv()
|
||||
self.env.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL)
|
||||
self.db = TestDB(self.env)
|
||||
self.db.open(self.db_name, db.DB_HASH, db.DB_CREATE)
|
||||
self.db.put('spam', 'eggs')
|
||||
assert self.db.get('spam') == None, \
|
||||
"overridden dbobj.DB.put() method failed [1]"
|
||||
assert self.db.get('SPAM') == 'eggs', \
|
||||
"overridden dbobj.DB.put() method failed [2]"
|
||||
self.db.close()
|
||||
self.env.close()
|
||||
|
||||
def test02_dbobj_dict_interface(self):
|
||||
self.env = dbobj.DBEnv()
|
||||
self.env.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL)
|
||||
self.db = dbobj.DB(self.env)
|
||||
self.db.open(self.db_name+'02', db.DB_HASH, db.DB_CREATE)
|
||||
# __setitem__
|
||||
self.db['spam'] = 'eggs'
|
||||
# __len__
|
||||
assert len(self.db) == 1
|
||||
# __getitem__
|
||||
assert self.db['spam'] == 'eggs'
|
||||
# __del__
|
||||
del self.db['spam']
|
||||
assert self.db.get('spam') == None, "dbobj __del__ failed"
|
||||
self.db.close()
|
||||
self.env.close()
|
||||
|
||||
def test03_dbobj_type_before_open(self):
|
||||
# Ensure this doesn't cause a segfault.
|
||||
self.assertRaises(db.DBInvalidArgError, db.DB().type)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
def test_suite():
|
||||
return unittest.makeSuite(dbobjTestCase)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(defaultTest='test_suite')
|
|
@ -1,306 +0,0 @@
|
|||
"""
|
||||
TestCases for checking dbShelve objects.
|
||||
"""
|
||||
|
||||
import sys, os, string
|
||||
import tempfile, random
|
||||
from pprint import pprint
|
||||
from types import *
|
||||
import unittest
|
||||
|
||||
try:
|
||||
# For Pythons w/distutils pybsddb
|
||||
from bsddb3 import db, dbshelve
|
||||
except ImportError:
|
||||
# For Python 2.3
|
||||
from bsddb import db, dbshelve
|
||||
|
||||
from test_all import verbose
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
# We want the objects to be comparable so we can test dbshelve.values
|
||||
# later on.
|
||||
class DataClass:
|
||||
def __init__(self):
|
||||
self.value = random.random()
|
||||
|
||||
def __cmp__(self, other):
|
||||
return cmp(self.value, other)
|
||||
|
||||
class DBShelveTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.filename = tempfile.mktemp()
|
||||
self.do_open()
|
||||
|
||||
def tearDown(self):
|
||||
self.do_close()
|
||||
try:
|
||||
os.remove(self.filename)
|
||||
except os.error:
|
||||
pass
|
||||
|
||||
def populateDB(self, d):
|
||||
for x in string.letters:
|
||||
d['S' + x] = 10 * x # add a string
|
||||
d['I' + x] = ord(x) # add an integer
|
||||
d['L' + x] = [x] * 10 # add a list
|
||||
|
||||
inst = DataClass() # add an instance
|
||||
inst.S = 10 * x
|
||||
inst.I = ord(x)
|
||||
inst.L = [x] * 10
|
||||
d['O' + x] = inst
|
||||
|
||||
|
||||
# overridable in derived classes to affect how the shelf is created/opened
|
||||
def do_open(self):
|
||||
self.d = dbshelve.open(self.filename)
|
||||
|
||||
# and closed...
|
||||
def do_close(self):
|
||||
self.d.close()
|
||||
|
||||
|
||||
|
||||
def test01_basics(self):
|
||||
if verbose:
|
||||
print '\n', '-=' * 30
|
||||
print "Running %s.test01_basics..." % self.__class__.__name__
|
||||
|
||||
self.populateDB(self.d)
|
||||
self.d.sync()
|
||||
self.do_close()
|
||||
self.do_open()
|
||||
d = self.d
|
||||
|
||||
l = len(d)
|
||||
k = d.keys()
|
||||
s = d.stat()
|
||||
f = d.fd()
|
||||
|
||||
if verbose:
|
||||
print "length:", l
|
||||
print "keys:", k
|
||||
print "stats:", s
|
||||
|
||||
assert 0 == d.has_key('bad key')
|
||||
assert 1 == d.has_key('IA')
|
||||
assert 1 == d.has_key('OA')
|
||||
|
||||
d.delete('IA')
|
||||
del d['OA']
|
||||
assert 0 == d.has_key('IA')
|
||||
assert 0 == d.has_key('OA')
|
||||
assert len(d) == l-2
|
||||
|
||||
values = []
|
||||
for key in d.keys():
|
||||
value = d[key]
|
||||
values.append(value)
|
||||
if verbose:
|
||||
print "%s: %s" % (key, value)
|
||||
self.checkrec(key, value)
|
||||
|
||||
dbvalues = d.values()
|
||||
assert len(dbvalues) == len(d.keys())
|
||||
values.sort()
|
||||
dbvalues.sort()
|
||||
assert values == dbvalues
|
||||
|
||||
items = d.items()
|
||||
assert len(items) == len(values)
|
||||
|
||||
for key, value in items:
|
||||
self.checkrec(key, value)
|
||||
|
||||
assert d.get('bad key') == None
|
||||
assert d.get('bad key', None) == None
|
||||
assert d.get('bad key', 'a string') == 'a string'
|
||||
assert d.get('bad key', [1, 2, 3]) == [1, 2, 3]
|
||||
|
||||
d.set_get_returns_none(0)
|
||||
self.assertRaises(db.DBNotFoundError, d.get, 'bad key')
|
||||
d.set_get_returns_none(1)
|
||||
|
||||
d.put('new key', 'new data')
|
||||
assert d.get('new key') == 'new data'
|
||||
assert d['new key'] == 'new data'
|
||||
|
||||
|
||||
|
||||
def test02_cursors(self):
|
||||
if verbose:
|
||||
print '\n', '-=' * 30
|
||||
print "Running %s.test02_cursors..." % self.__class__.__name__
|
||||
|
||||
self.populateDB(self.d)
|
||||
d = self.d
|
||||
|
||||
count = 0
|
||||
c = d.cursor()
|
||||
rec = c.first()
|
||||
while rec is not None:
|
||||
count = count + 1
|
||||
if verbose:
|
||||
print rec
|
||||
key, value = rec
|
||||
self.checkrec(key, value)
|
||||
rec = c.next()
|
||||
del c
|
||||
|
||||
assert count == len(d)
|
||||
|
||||
count = 0
|
||||
c = d.cursor()
|
||||
rec = c.last()
|
||||
while rec is not None:
|
||||
count = count + 1
|
||||
if verbose:
|
||||
print rec
|
||||
key, value = rec
|
||||
self.checkrec(key, value)
|
||||
rec = c.prev()
|
||||
|
||||
assert count == len(d)
|
||||
|
||||
c.set('SS')
|
||||
key, value = c.current()
|
||||
self.checkrec(key, value)
|
||||
del c
|
||||
|
||||
|
||||
|
||||
def checkrec(self, key, value):
|
||||
x = key[1]
|
||||
if key[0] == 'S':
|
||||
assert type(value) == StringType
|
||||
assert value == 10 * x
|
||||
|
||||
elif key[0] == 'I':
|
||||
assert type(value) == IntType
|
||||
assert value == ord(x)
|
||||
|
||||
elif key[0] == 'L':
|
||||
assert type(value) == ListType
|
||||
assert value == [x] * 10
|
||||
|
||||
elif key[0] == 'O':
|
||||
assert type(value) == InstanceType
|
||||
assert value.S == 10 * x
|
||||
assert value.I == ord(x)
|
||||
assert value.L == [x] * 10
|
||||
|
||||
else:
|
||||
raise AssertionError, 'Unknown key type, fix the test'
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
class BasicShelveTestCase(DBShelveTestCase):
|
||||
def do_open(self):
|
||||
self.d = dbshelve.DBShelf()
|
||||
self.d.open(self.filename, self.dbtype, self.dbflags)
|
||||
|
||||
def do_close(self):
|
||||
self.d.close()
|
||||
|
||||
|
||||
class BTreeShelveTestCase(BasicShelveTestCase):
|
||||
dbtype = db.DB_BTREE
|
||||
dbflags = db.DB_CREATE
|
||||
|
||||
|
||||
class HashShelveTestCase(BasicShelveTestCase):
|
||||
dbtype = db.DB_HASH
|
||||
dbflags = db.DB_CREATE
|
||||
|
||||
|
||||
class ThreadBTreeShelveTestCase(BasicShelveTestCase):
|
||||
dbtype = db.DB_BTREE
|
||||
dbflags = db.DB_CREATE | db.DB_THREAD
|
||||
|
||||
|
||||
class ThreadHashShelveTestCase(BasicShelveTestCase):
|
||||
dbtype = db.DB_HASH
|
||||
dbflags = db.DB_CREATE | db.DB_THREAD
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
class BasicEnvShelveTestCase(DBShelveTestCase):
|
||||
def do_open(self):
|
||||
self.homeDir = homeDir = os.path.join(
|
||||
os.path.dirname(sys.argv[0]), 'db_home')
|
||||
try: os.mkdir(homeDir)
|
||||
except os.error: pass
|
||||
self.env = db.DBEnv()
|
||||
self.env.open(homeDir, self.envflags | db.DB_INIT_MPOOL | db.DB_CREATE)
|
||||
|
||||
self.filename = os.path.split(self.filename)[1]
|
||||
self.d = dbshelve.DBShelf(self.env)
|
||||
self.d.open(self.filename, self.dbtype, self.dbflags)
|
||||
|
||||
|
||||
def do_close(self):
|
||||
self.d.close()
|
||||
self.env.close()
|
||||
|
||||
|
||||
def tearDown(self):
|
||||
self.do_close()
|
||||
import glob
|
||||
files = glob.glob(os.path.join(self.homeDir, '*'))
|
||||
for file in files:
|
||||
os.remove(file)
|
||||
|
||||
|
||||
|
||||
class EnvBTreeShelveTestCase(BasicEnvShelveTestCase):
|
||||
envflags = 0
|
||||
dbtype = db.DB_BTREE
|
||||
dbflags = db.DB_CREATE
|
||||
|
||||
|
||||
class EnvHashShelveTestCase(BasicEnvShelveTestCase):
|
||||
envflags = 0
|
||||
dbtype = db.DB_HASH
|
||||
dbflags = db.DB_CREATE
|
||||
|
||||
|
||||
class EnvThreadBTreeShelveTestCase(BasicEnvShelveTestCase):
|
||||
envflags = db.DB_THREAD
|
||||
dbtype = db.DB_BTREE
|
||||
dbflags = db.DB_CREATE | db.DB_THREAD
|
||||
|
||||
|
||||
class EnvThreadHashShelveTestCase(BasicEnvShelveTestCase):
|
||||
envflags = db.DB_THREAD
|
||||
dbtype = db.DB_HASH
|
||||
dbflags = db.DB_CREATE | db.DB_THREAD
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# TODO: Add test cases for a DBShelf in a RECNO DB.
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
def test_suite():
|
||||
suite = unittest.TestSuite()
|
||||
|
||||
suite.addTest(unittest.makeSuite(DBShelveTestCase))
|
||||
suite.addTest(unittest.makeSuite(BTreeShelveTestCase))
|
||||
suite.addTest(unittest.makeSuite(HashShelveTestCase))
|
||||
suite.addTest(unittest.makeSuite(ThreadBTreeShelveTestCase))
|
||||
suite.addTest(unittest.makeSuite(ThreadHashShelveTestCase))
|
||||
suite.addTest(unittest.makeSuite(EnvBTreeShelveTestCase))
|
||||
suite.addTest(unittest.makeSuite(EnvHashShelveTestCase))
|
||||
suite.addTest(unittest.makeSuite(EnvThreadBTreeShelveTestCase))
|
||||
suite.addTest(unittest.makeSuite(EnvThreadHashShelveTestCase))
|
||||
|
||||
return suite
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(defaultTest='test_suite')
|
|
@ -1,383 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
#-----------------------------------------------------------------------
|
||||
# A test suite for the table interface built on bsddb.db
|
||||
#-----------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (C) 2000, 2001 by Autonomous Zone Industries
|
||||
# Copyright (C) 2002 Gregory P. Smith
|
||||
#
|
||||
# March 20, 2000
|
||||
#
|
||||
# License: This is free software. You may use this software for any
|
||||
# purpose including modification/redistribution, so long as
|
||||
# this header remains intact and that you do not claim any
|
||||
# rights of ownership or authorship of this software. This
|
||||
# software has been tested, but no warranty is expressed or
|
||||
# implied.
|
||||
#
|
||||
# -- Gregory P. Smith <greg@electricrain.com>
|
||||
#
|
||||
# $Id: test_dbtables.py 46737 2006-06-08 05:38:11Z gregory.p.smith $
|
||||
|
||||
import sys, os, re
|
||||
try:
|
||||
import cPickle
|
||||
pickle = cPickle
|
||||
except ImportError:
|
||||
import pickle
|
||||
|
||||
import unittest
|
||||
from test_all import verbose
|
||||
|
||||
try:
|
||||
# For Pythons w/distutils pybsddb
|
||||
from bsddb3 import db, dbtables
|
||||
except ImportError:
|
||||
# For Python 2.3
|
||||
from bsddb import db, dbtables
|
||||
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
class TableDBTestCase(unittest.TestCase):
|
||||
db_home = 'db_home'
|
||||
db_name = 'test-table.db'
|
||||
|
||||
def setUp(self):
|
||||
homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
|
||||
self.homeDir = homeDir
|
||||
try: os.mkdir(homeDir)
|
||||
except os.error: pass
|
||||
self.tdb = dbtables.bsdTableDB(
|
||||
filename='tabletest.db', dbhome=homeDir, create=1)
|
||||
|
||||
def tearDown(self):
|
||||
self.tdb.close()
|
||||
import glob
|
||||
files = glob.glob(os.path.join(self.homeDir, '*'))
|
||||
for file in files:
|
||||
os.remove(file)
|
||||
|
||||
def test01(self):
|
||||
tabname = "test01"
|
||||
colname = 'cool numbers'
|
||||
try:
|
||||
self.tdb.Drop(tabname)
|
||||
except dbtables.TableDBError:
|
||||
pass
|
||||
self.tdb.CreateTable(tabname, [colname])
|
||||
self.tdb.Insert(tabname, {colname: pickle.dumps(3.14159, 1)})
|
||||
|
||||
if verbose:
|
||||
self.tdb._db_print()
|
||||
|
||||
values = self.tdb.Select(
|
||||
tabname, [colname], conditions={colname: None})
|
||||
|
||||
colval = pickle.loads(values[0][colname])
|
||||
assert(colval > 3.141 and colval < 3.142)
|
||||
|
||||
|
||||
def test02(self):
|
||||
tabname = "test02"
|
||||
col0 = 'coolness factor'
|
||||
col1 = 'but can it fly?'
|
||||
col2 = 'Species'
|
||||
testinfo = [
|
||||
{col0: pickle.dumps(8, 1), col1: 'no', col2: 'Penguin'},
|
||||
{col0: pickle.dumps(-1, 1), col1: 'no', col2: 'Turkey'},
|
||||
{col0: pickle.dumps(9, 1), col1: 'yes', col2: 'SR-71A Blackbird'}
|
||||
]
|
||||
|
||||
try:
|
||||
self.tdb.Drop(tabname)
|
||||
except dbtables.TableDBError:
|
||||
pass
|
||||
self.tdb.CreateTable(tabname, [col0, col1, col2])
|
||||
for row in testinfo :
|
||||
self.tdb.Insert(tabname, row)
|
||||
|
||||
values = self.tdb.Select(tabname, [col2],
|
||||
conditions={col0: lambda x: pickle.loads(x) >= 8})
|
||||
|
||||
assert len(values) == 2
|
||||
if values[0]['Species'] == 'Penguin' :
|
||||
assert values[1]['Species'] == 'SR-71A Blackbird'
|
||||
elif values[0]['Species'] == 'SR-71A Blackbird' :
|
||||
assert values[1]['Species'] == 'Penguin'
|
||||
else :
|
||||
if verbose:
|
||||
print "values= %r" % (values,)
|
||||
raise "Wrong values returned!"
|
||||
|
||||
def test03(self):
|
||||
tabname = "test03"
|
||||
try:
|
||||
self.tdb.Drop(tabname)
|
||||
except dbtables.TableDBError:
|
||||
pass
|
||||
if verbose:
|
||||
print '...before CreateTable...'
|
||||
self.tdb._db_print()
|
||||
self.tdb.CreateTable(tabname, ['a', 'b', 'c', 'd', 'e'])
|
||||
if verbose:
|
||||
print '...after CreateTable...'
|
||||
self.tdb._db_print()
|
||||
self.tdb.Drop(tabname)
|
||||
if verbose:
|
||||
print '...after Drop...'
|
||||
self.tdb._db_print()
|
||||
self.tdb.CreateTable(tabname, ['a', 'b', 'c', 'd', 'e'])
|
||||
|
||||
try:
|
||||
self.tdb.Insert(tabname,
|
||||
{'a': "",
|
||||
'e': pickle.dumps([{4:5, 6:7}, 'foo'], 1),
|
||||
'f': "Zero"})
|
||||
assert 0
|
||||
except dbtables.TableDBError:
|
||||
pass
|
||||
|
||||
try:
|
||||
self.tdb.Select(tabname, [], conditions={'foo': '123'})
|
||||
assert 0
|
||||
except dbtables.TableDBError:
|
||||
pass
|
||||
|
||||
self.tdb.Insert(tabname,
|
||||
{'a': '42',
|
||||
'b': "bad",
|
||||
'c': "meep",
|
||||
'e': 'Fuzzy wuzzy was a bear'})
|
||||
self.tdb.Insert(tabname,
|
||||
{'a': '581750',
|
||||
'b': "good",
|
||||
'd': "bla",
|
||||
'c': "black",
|
||||
'e': 'fuzzy was here'})
|
||||
self.tdb.Insert(tabname,
|
||||
{'a': '800000',
|
||||
'b': "good",
|
||||
'd': "bla",
|
||||
'c': "black",
|
||||
'e': 'Fuzzy wuzzy is a bear'})
|
||||
|
||||
if verbose:
|
||||
self.tdb._db_print()
|
||||
|
||||
# this should return two rows
|
||||
values = self.tdb.Select(tabname, ['b', 'a', 'd'],
|
||||
conditions={'e': re.compile('wuzzy').search,
|
||||
'a': re.compile('^[0-9]+$').match})
|
||||
assert len(values) == 2
|
||||
|
||||
# now lets delete one of them and try again
|
||||
self.tdb.Delete(tabname, conditions={'b': dbtables.ExactCond('good')})
|
||||
values = self.tdb.Select(
|
||||
tabname, ['a', 'd', 'b'],
|
||||
conditions={'e': dbtables.PrefixCond('Fuzzy')})
|
||||
assert len(values) == 1
|
||||
assert values[0]['d'] == None
|
||||
|
||||
values = self.tdb.Select(tabname, ['b'],
|
||||
conditions={'c': lambda c: c == 'meep'})
|
||||
assert len(values) == 1
|
||||
assert values[0]['b'] == "bad"
|
||||
|
||||
|
||||
def test04_MultiCondSelect(self):
|
||||
tabname = "test04_MultiCondSelect"
|
||||
try:
|
||||
self.tdb.Drop(tabname)
|
||||
except dbtables.TableDBError:
|
||||
pass
|
||||
self.tdb.CreateTable(tabname, ['a', 'b', 'c', 'd', 'e'])
|
||||
|
||||
try:
|
||||
self.tdb.Insert(tabname,
|
||||
{'a': "",
|
||||
'e': pickle.dumps([{4:5, 6:7}, 'foo'], 1),
|
||||
'f': "Zero"})
|
||||
assert 0
|
||||
except dbtables.TableDBError:
|
||||
pass
|
||||
|
||||
self.tdb.Insert(tabname, {'a': "A", 'b': "B", 'c': "C", 'd': "D",
|
||||
'e': "E"})
|
||||
self.tdb.Insert(tabname, {'a': "-A", 'b': "-B", 'c': "-C", 'd': "-D",
|
||||
'e': "-E"})
|
||||
self.tdb.Insert(tabname, {'a': "A-", 'b': "B-", 'c': "C-", 'd': "D-",
|
||||
'e': "E-"})
|
||||
|
||||
if verbose:
|
||||
self.tdb._db_print()
|
||||
|
||||
# This select should return 0 rows. it is designed to test
|
||||
# the bug identified and fixed in sourceforge bug # 590449
|
||||
# (Big Thanks to "Rob Tillotson (n9mtb)" for tracking this down
|
||||
# and supplying a fix!! This one caused many headaches to say
|
||||
# the least...)
|
||||
values = self.tdb.Select(tabname, ['b', 'a', 'd'],
|
||||
conditions={'e': dbtables.ExactCond('E'),
|
||||
'a': dbtables.ExactCond('A'),
|
||||
'd': dbtables.PrefixCond('-')
|
||||
} )
|
||||
assert len(values) == 0, values
|
||||
|
||||
|
||||
def test_CreateOrExtend(self):
|
||||
tabname = "test_CreateOrExtend"
|
||||
|
||||
self.tdb.CreateOrExtendTable(
|
||||
tabname, ['name', 'taste', 'filling', 'alcohol content', 'price'])
|
||||
try:
|
||||
self.tdb.Insert(tabname,
|
||||
{'taste': 'crap',
|
||||
'filling': 'no',
|
||||
'is it Guinness?': 'no'})
|
||||
assert 0, "Insert should've failed due to bad column name"
|
||||
except:
|
||||
pass
|
||||
self.tdb.CreateOrExtendTable(tabname,
|
||||
['name', 'taste', 'is it Guinness?'])
|
||||
|
||||
# these should both succeed as the table should contain the union of both sets of columns.
|
||||
self.tdb.Insert(tabname, {'taste': 'crap', 'filling': 'no',
|
||||
'is it Guinness?': 'no'})
|
||||
self.tdb.Insert(tabname, {'taste': 'great', 'filling': 'yes',
|
||||
'is it Guinness?': 'yes',
|
||||
'name': 'Guinness'})
|
||||
|
||||
|
||||
def test_CondObjs(self):
|
||||
tabname = "test_CondObjs"
|
||||
|
||||
self.tdb.CreateTable(tabname, ['a', 'b', 'c', 'd', 'e', 'p'])
|
||||
|
||||
self.tdb.Insert(tabname, {'a': "the letter A",
|
||||
'b': "the letter B",
|
||||
'c': "is for cookie"})
|
||||
self.tdb.Insert(tabname, {'a': "is for aardvark",
|
||||
'e': "the letter E",
|
||||
'c': "is for cookie",
|
||||
'd': "is for dog"})
|
||||
self.tdb.Insert(tabname, {'a': "the letter A",
|
||||
'e': "the letter E",
|
||||
'c': "is for cookie",
|
||||
'p': "is for Python"})
|
||||
|
||||
values = self.tdb.Select(
|
||||
tabname, ['p', 'e'],
|
||||
conditions={'e': dbtables.PrefixCond('the l')})
|
||||
assert len(values) == 2, values
|
||||
assert values[0]['e'] == values[1]['e'], values
|
||||
assert values[0]['p'] != values[1]['p'], values
|
||||
|
||||
values = self.tdb.Select(
|
||||
tabname, ['d', 'a'],
|
||||
conditions={'a': dbtables.LikeCond('%aardvark%')})
|
||||
assert len(values) == 1, values
|
||||
assert values[0]['d'] == "is for dog", values
|
||||
assert values[0]['a'] == "is for aardvark", values
|
||||
|
||||
values = self.tdb.Select(tabname, None,
|
||||
{'b': dbtables.Cond(),
|
||||
'e':dbtables.LikeCond('%letter%'),
|
||||
'a':dbtables.PrefixCond('is'),
|
||||
'd':dbtables.ExactCond('is for dog'),
|
||||
'c':dbtables.PrefixCond('is for'),
|
||||
'p':lambda s: not s})
|
||||
assert len(values) == 1, values
|
||||
assert values[0]['d'] == "is for dog", values
|
||||
assert values[0]['a'] == "is for aardvark", values
|
||||
|
||||
def test_Delete(self):
|
||||
tabname = "test_Delete"
|
||||
self.tdb.CreateTable(tabname, ['x', 'y', 'z'])
|
||||
|
||||
# prior to 2001-05-09 there was a bug where Delete() would
|
||||
# fail if it encountered any rows that did not have values in
|
||||
# every column.
|
||||
# Hunted and Squashed by <Donwulff> (Jukka Santala - donwulff@nic.fi)
|
||||
self.tdb.Insert(tabname, {'x': 'X1', 'y':'Y1'})
|
||||
self.tdb.Insert(tabname, {'x': 'X2', 'y':'Y2', 'z': 'Z2'})
|
||||
|
||||
self.tdb.Delete(tabname, conditions={'x': dbtables.PrefixCond('X')})
|
||||
values = self.tdb.Select(tabname, ['y'],
|
||||
conditions={'x': dbtables.PrefixCond('X')})
|
||||
assert len(values) == 0
|
||||
|
||||
def test_Modify(self):
|
||||
tabname = "test_Modify"
|
||||
self.tdb.CreateTable(tabname, ['Name', 'Type', 'Access'])
|
||||
|
||||
self.tdb.Insert(tabname, {'Name': 'Index to MP3 files.doc',
|
||||
'Type': 'Word', 'Access': '8'})
|
||||
self.tdb.Insert(tabname, {'Name': 'Nifty.MP3', 'Access': '1'})
|
||||
self.tdb.Insert(tabname, {'Type': 'Unknown', 'Access': '0'})
|
||||
|
||||
def set_type(type):
|
||||
if type == None:
|
||||
return 'MP3'
|
||||
return type
|
||||
|
||||
def increment_access(count):
|
||||
return str(int(count)+1)
|
||||
|
||||
def remove_value(value):
|
||||
return None
|
||||
|
||||
self.tdb.Modify(tabname,
|
||||
conditions={'Access': dbtables.ExactCond('0')},
|
||||
mappings={'Access': remove_value})
|
||||
self.tdb.Modify(tabname,
|
||||
conditions={'Name': dbtables.LikeCond('%MP3%')},
|
||||
mappings={'Type': set_type})
|
||||
self.tdb.Modify(tabname,
|
||||
conditions={'Name': dbtables.LikeCond('%')},
|
||||
mappings={'Access': increment_access})
|
||||
|
||||
try:
|
||||
self.tdb.Modify(tabname,
|
||||
conditions={'Name': dbtables.LikeCond('%')},
|
||||
mappings={'Access': 'What is your quest?'})
|
||||
except TypeError:
|
||||
# success, the string value in mappings isn't callable
|
||||
pass
|
||||
else:
|
||||
raise RuntimeError, "why was TypeError not raised for bad callable?"
|
||||
|
||||
# Delete key in select conditions
|
||||
values = self.tdb.Select(
|
||||
tabname, None,
|
||||
conditions={'Type': dbtables.ExactCond('Unknown')})
|
||||
assert len(values) == 1, values
|
||||
assert values[0]['Name'] == None, values
|
||||
assert values[0]['Access'] == None, values
|
||||
|
||||
# Modify value by select conditions
|
||||
values = self.tdb.Select(
|
||||
tabname, None,
|
||||
conditions={'Name': dbtables.ExactCond('Nifty.MP3')})
|
||||
assert len(values) == 1, values
|
||||
assert values[0]['Type'] == "MP3", values
|
||||
assert values[0]['Access'] == "2", values
|
||||
|
||||
# Make sure change applied only to select conditions
|
||||
values = self.tdb.Select(
|
||||
tabname, None, conditions={'Name': dbtables.LikeCond('%doc%')})
|
||||
assert len(values) == 1, values
|
||||
assert values[0]['Type'] == "Word", values
|
||||
assert values[0]['Access'] == "9", values
|
||||
|
||||
|
||||
def test_suite():
|
||||
suite = unittest.TestSuite()
|
||||
suite.addTest(unittest.makeSuite(TableDBTestCase))
|
||||
return suite
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(defaultTest='test_suite')
|
|
@ -1,107 +0,0 @@
|
|||
"""TestCases for checking that it does not segfault when a DBEnv object
|
||||
is closed before its DB objects.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
import glob
|
||||
import unittest
|
||||
|
||||
try:
|
||||
# For Pythons w/distutils pybsddb
|
||||
from bsddb3 import db
|
||||
except ImportError:
|
||||
# For Python 2.3
|
||||
from bsddb import db
|
||||
|
||||
from test_all import verbose
|
||||
|
||||
# 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 = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
|
||||
try: os.mkdir(self.homeDir)
|
||||
except os.error: pass
|
||||
tempfile.tempdir = self.homeDir
|
||||
self.filename = os.path.split(tempfile.mktemp())[1]
|
||||
tempfile.tempdir = None
|
||||
|
||||
def tearDown(self):
|
||||
files = glob.glob(os.path.join(self.homeDir, '*'))
|
||||
for file in files:
|
||||
os.remove(file)
|
||||
|
||||
|
||||
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,
|
||||
0666)
|
||||
|
||||
d = db.DB(dbenv)
|
||||
d.open(self.filename, db.DB_BTREE, db.DB_CREATE | db.DB_THREAD, 0666)
|
||||
|
||||
try:
|
||||
dbenv.close()
|
||||
except db.DBError:
|
||||
try:
|
||||
d.close()
|
||||
except db.DBError:
|
||||
return
|
||||
assert 0, \
|
||||
"DB close did not raise an exception about its "\
|
||||
"DBEnv being trashed"
|
||||
|
||||
# XXX This may fail when using older versions of BerkeleyDB.
|
||||
# E.g. 3.2.9 never raised the exception.
|
||||
assert 0, "dbenv did not raise an exception about its DB being open"
|
||||
|
||||
|
||||
def test02_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,
|
||||
0666)
|
||||
|
||||
d = db.DB(dbenv)
|
||||
d.open(self.filename, db.DB_BTREE, db.DB_CREATE | db.DB_THREAD, 0666)
|
||||
|
||||
try:
|
||||
dbenv.close()
|
||||
except db.DBError:
|
||||
pass # good, it should raise an exception
|
||||
|
||||
del d
|
||||
try:
|
||||
import gc
|
||||
except ImportError:
|
||||
gc = None
|
||||
if gc:
|
||||
# force d.__del__ [DB_dealloc] to be called
|
||||
gc.collect()
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
def test_suite():
|
||||
suite = unittest.TestSuite()
|
||||
suite.addTest(unittest.makeSuite(DBEnvClosedEarlyCrash))
|
||||
return suite
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(defaultTest='test_suite')
|
|
@ -1,101 +0,0 @@
|
|||
"""
|
||||
TestCases for checking set_get_returns_none.
|
||||
"""
|
||||
|
||||
import sys, os, string
|
||||
import tempfile
|
||||
from pprint import pprint
|
||||
import unittest
|
||||
|
||||
try:
|
||||
# For Pythons w/distutils pybsddb
|
||||
from bsddb3 import db
|
||||
except ImportError:
|
||||
# For Python 2.3
|
||||
from bsddb import db
|
||||
|
||||
from test_all import verbose
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
class GetReturnsNoneTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.filename = tempfile.mktemp()
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
os.remove(self.filename)
|
||||
except os.error:
|
||||
pass
|
||||
|
||||
|
||||
def test01_get_returns_none(self):
|
||||
d = db.DB()
|
||||
d.open(self.filename, db.DB_BTREE, db.DB_CREATE)
|
||||
d.set_get_returns_none(1)
|
||||
|
||||
for x in string.letters:
|
||||
d.put(x, x * 40)
|
||||
|
||||
data = d.get('bad key')
|
||||
assert data == None
|
||||
|
||||
data = d.get('a')
|
||||
assert data == 'a'*40
|
||||
|
||||
count = 0
|
||||
c = d.cursor()
|
||||
rec = c.first()
|
||||
while rec:
|
||||
count = count + 1
|
||||
rec = c.next()
|
||||
|
||||
assert rec == None
|
||||
assert count == 52
|
||||
|
||||
c.close()
|
||||
d.close()
|
||||
|
||||
|
||||
def test02_get_raises_exception(self):
|
||||
d = db.DB()
|
||||
d.open(self.filename, db.DB_BTREE, db.DB_CREATE)
|
||||
d.set_get_returns_none(0)
|
||||
|
||||
for x in string.letters:
|
||||
d.put(x, x * 40)
|
||||
|
||||
self.assertRaises(db.DBNotFoundError, d.get, 'bad key')
|
||||
self.assertRaises(KeyError, d.get, 'bad key')
|
||||
|
||||
data = d.get('a')
|
||||
assert data == 'a'*40
|
||||
|
||||
count = 0
|
||||
exceptionHappened = 0
|
||||
c = d.cursor()
|
||||
rec = c.first()
|
||||
while rec:
|
||||
count = count + 1
|
||||
try:
|
||||
rec = c.next()
|
||||
except db.DBNotFoundError: # end of the records
|
||||
exceptionHappened = 1
|
||||
break
|
||||
|
||||
assert rec != None
|
||||
assert exceptionHappened
|
||||
assert count == 52
|
||||
|
||||
c.close()
|
||||
d.close()
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
def test_suite():
|
||||
return unittest.makeSuite(GetReturnsNoneTestCase)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(defaultTest='test_suite')
|
|
@ -1,120 +0,0 @@
|
|||
"""TestCases for using the DB.join and DBCursor.join_item methods.
|
||||
"""
|
||||
|
||||
import sys, os, string
|
||||
import tempfile
|
||||
import time
|
||||
from pprint import pprint
|
||||
|
||||
try:
|
||||
from threading import Thread, currentThread
|
||||
have_threads = 1
|
||||
except ImportError:
|
||||
have_threads = 0
|
||||
|
||||
import unittest
|
||||
from test_all import verbose
|
||||
|
||||
try:
|
||||
# For Pythons w/distutils pybsddb
|
||||
from bsddb3 import db, dbshelve
|
||||
except ImportError:
|
||||
# For Python 2.3
|
||||
from bsddb import db, dbshelve
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
ProductIndex = [
|
||||
('apple', "Convenience Store"),
|
||||
('blueberry', "Farmer's Market"),
|
||||
('shotgun', "S-Mart"), # Aisle 12
|
||||
('pear', "Farmer's Market"),
|
||||
('chainsaw', "S-Mart"), # "Shop smart. Shop S-Mart!"
|
||||
('strawberry', "Farmer's Market"),
|
||||
]
|
||||
|
||||
ColorIndex = [
|
||||
('blue', "blueberry"),
|
||||
('red', "apple"),
|
||||
('red', "chainsaw"),
|
||||
('red', "strawberry"),
|
||||
('yellow', "peach"),
|
||||
('yellow', "pear"),
|
||||
('black', "shotgun"),
|
||||
]
|
||||
|
||||
class JoinTestCase(unittest.TestCase):
|
||||
keytype = ''
|
||||
|
||||
def setUp(self):
|
||||
self.filename = self.__class__.__name__ + '.db'
|
||||
homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
|
||||
self.homeDir = homeDir
|
||||
try: os.mkdir(homeDir)
|
||||
except os.error: pass
|
||||
self.env = db.DBEnv()
|
||||
self.env.open(homeDir, db.DB_CREATE | db.DB_INIT_MPOOL | db.DB_INIT_LOCK )
|
||||
|
||||
def tearDown(self):
|
||||
self.env.close()
|
||||
import glob
|
||||
files = glob.glob(os.path.join(self.homeDir, '*'))
|
||||
for file in files:
|
||||
os.remove(file)
|
||||
|
||||
def test01_join(self):
|
||||
if verbose:
|
||||
print '\n', '-=' * 30
|
||||
print "Running %s.test01_join..." % \
|
||||
self.__class__.__name__
|
||||
|
||||
# create and populate primary index
|
||||
priDB = db.DB(self.env)
|
||||
priDB.open(self.filename, "primary", db.DB_BTREE, db.DB_CREATE)
|
||||
map(lambda t, priDB=priDB: apply(priDB.put, t), ProductIndex)
|
||||
|
||||
# create and populate secondary index
|
||||
secDB = db.DB(self.env)
|
||||
secDB.set_flags(db.DB_DUP | db.DB_DUPSORT)
|
||||
secDB.open(self.filename, "secondary", db.DB_BTREE, db.DB_CREATE)
|
||||
map(lambda t, secDB=secDB: apply(secDB.put, t), ColorIndex)
|
||||
|
||||
sCursor = None
|
||||
jCursor = None
|
||||
try:
|
||||
# lets look up all of the red Products
|
||||
sCursor = secDB.cursor()
|
||||
# Don't do the .set() in an assert, or you can get a bogus failure
|
||||
# when running python -O
|
||||
tmp = sCursor.set('red')
|
||||
assert tmp
|
||||
|
||||
# FIXME: jCursor doesn't properly hold a reference to its
|
||||
# cursors, if they are closed before jcursor is used it
|
||||
# can cause a crash.
|
||||
jCursor = priDB.join([sCursor])
|
||||
|
||||
if jCursor.get(0) != ('apple', "Convenience Store"):
|
||||
self.fail("join cursor positioned wrong")
|
||||
if jCursor.join_item() != 'chainsaw':
|
||||
self.fail("DBCursor.join_item returned wrong item")
|
||||
if jCursor.get(0)[0] != 'strawberry':
|
||||
self.fail("join cursor returned wrong thing")
|
||||
if jCursor.get(0): # there were only three red items to return
|
||||
self.fail("join cursor returned too many items")
|
||||
finally:
|
||||
if jCursor:
|
||||
jCursor.close()
|
||||
if sCursor:
|
||||
sCursor.close()
|
||||
priDB.close()
|
||||
secDB.close()
|
||||
|
||||
|
||||
def test_suite():
|
||||
suite = unittest.TestSuite()
|
||||
|
||||
suite.addTest(unittest.makeSuite(JoinTestCase))
|
||||
|
||||
return suite
|
|
@ -1,143 +0,0 @@
|
|||
"""
|
||||
TestCases for testing the locking sub-system.
|
||||
"""
|
||||
|
||||
import sys, os, string
|
||||
import tempfile
|
||||
import time
|
||||
from pprint import pprint
|
||||
|
||||
try:
|
||||
from threading import Thread, currentThread
|
||||
have_threads = 1
|
||||
except ImportError:
|
||||
have_threads = 0
|
||||
|
||||
|
||||
import unittest
|
||||
from test_all import verbose
|
||||
|
||||
try:
|
||||
# For Pythons w/distutils pybsddb
|
||||
from bsddb3 import db
|
||||
except ImportError:
|
||||
# For Python 2.3
|
||||
from bsddb import db
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
class LockingTestCase(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
|
||||
self.homeDir = homeDir
|
||||
try: os.mkdir(homeDir)
|
||||
except os.error: pass
|
||||
self.env = db.DBEnv()
|
||||
self.env.open(homeDir, db.DB_THREAD | db.DB_INIT_MPOOL |
|
||||
db.DB_INIT_LOCK | db.DB_CREATE)
|
||||
|
||||
|
||||
def tearDown(self):
|
||||
self.env.close()
|
||||
import glob
|
||||
files = glob.glob(os.path.join(self.homeDir, '*'))
|
||||
for file in files:
|
||||
os.remove(file)
|
||||
|
||||
|
||||
def test01_simple(self):
|
||||
if verbose:
|
||||
print '\n', '-=' * 30
|
||||
print "Running %s.test01_simple..." % self.__class__.__name__
|
||||
|
||||
anID = self.env.lock_id()
|
||||
if verbose:
|
||||
print "locker ID: %s" % anID
|
||||
lock = self.env.lock_get(anID, "some locked thing", db.DB_LOCK_WRITE)
|
||||
if verbose:
|
||||
print "Aquired lock: %s" % lock
|
||||
time.sleep(1)
|
||||
self.env.lock_put(lock)
|
||||
if verbose:
|
||||
print "Released lock: %s" % lock
|
||||
|
||||
|
||||
|
||||
|
||||
def test02_threaded(self):
|
||||
if verbose:
|
||||
print '\n', '-=' * 30
|
||||
print "Running %s.test02_threaded..." % self.__class__.__name__
|
||||
|
||||
threads = []
|
||||
threads.append(Thread(target = self.theThread,
|
||||
args=(5, db.DB_LOCK_WRITE)))
|
||||
threads.append(Thread(target = self.theThread,
|
||||
args=(1, db.DB_LOCK_READ)))
|
||||
threads.append(Thread(target = self.theThread,
|
||||
args=(1, db.DB_LOCK_READ)))
|
||||
threads.append(Thread(target = self.theThread,
|
||||
args=(1, db.DB_LOCK_WRITE)))
|
||||
threads.append(Thread(target = self.theThread,
|
||||
args=(1, db.DB_LOCK_READ)))
|
||||
threads.append(Thread(target = self.theThread,
|
||||
args=(1, db.DB_LOCK_READ)))
|
||||
threads.append(Thread(target = self.theThread,
|
||||
args=(1, db.DB_LOCK_WRITE)))
|
||||
threads.append(Thread(target = self.theThread,
|
||||
args=(1, db.DB_LOCK_WRITE)))
|
||||
threads.append(Thread(target = self.theThread,
|
||||
args=(1, db.DB_LOCK_WRITE)))
|
||||
|
||||
for t in threads:
|
||||
t.start()
|
||||
for t in threads:
|
||||
t.join()
|
||||
|
||||
def test03_set_timeout(self):
|
||||
# test that the set_timeout call works
|
||||
if hasattr(self.env, 'set_timeout'):
|
||||
self.env.set_timeout(0, db.DB_SET_LOCK_TIMEOUT)
|
||||
self.env.set_timeout(0, db.DB_SET_TXN_TIMEOUT)
|
||||
self.env.set_timeout(123456, db.DB_SET_LOCK_TIMEOUT)
|
||||
self.env.set_timeout(7890123, db.DB_SET_TXN_TIMEOUT)
|
||||
|
||||
def theThread(self, sleepTime, lockType):
|
||||
name = currentThread().getName()
|
||||
if lockType == db.DB_LOCK_WRITE:
|
||||
lt = "write"
|
||||
else:
|
||||
lt = "read"
|
||||
|
||||
anID = self.env.lock_id()
|
||||
if verbose:
|
||||
print "%s: locker ID: %s" % (name, anID)
|
||||
|
||||
lock = self.env.lock_get(anID, "some locked thing", lockType)
|
||||
if verbose:
|
||||
print "%s: Aquired %s lock: %s" % (name, lt, lock)
|
||||
|
||||
time.sleep(sleepTime)
|
||||
|
||||
self.env.lock_put(lock)
|
||||
if verbose:
|
||||
print "%s: Released %s lock: %s" % (name, lt, lock)
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
def test_suite():
|
||||
suite = unittest.TestSuite()
|
||||
|
||||
if have_threads:
|
||||
suite.addTest(unittest.makeSuite(LockingTestCase))
|
||||
else:
|
||||
suite.addTest(unittest.makeSuite(LockingTestCase, 'test01'))
|
||||
|
||||
return suite
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(defaultTest='test_suite')
|
|
@ -1,64 +0,0 @@
|
|||
"""Miscellaneous bsddb module test cases
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
try:
|
||||
# For Pythons w/distutils pybsddb
|
||||
from bsddb3 import db, dbshelve, hashopen
|
||||
except ImportError:
|
||||
# For Python 2.3
|
||||
from bsddb import db, dbshelve, hashopen
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
class MiscTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.filename = self.__class__.__name__ + '.db'
|
||||
homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
|
||||
self.homeDir = homeDir
|
||||
try:
|
||||
os.mkdir(homeDir)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
os.remove(self.filename)
|
||||
except OSError:
|
||||
pass
|
||||
import glob
|
||||
files = glob.glob(os.path.join(self.homeDir, '*'))
|
||||
for file in files:
|
||||
os.remove(file)
|
||||
|
||||
def test01_badpointer(self):
|
||||
dbs = dbshelve.open(self.filename)
|
||||
dbs.close()
|
||||
self.assertRaises(db.DBError, dbs.get, "foo")
|
||||
|
||||
def test02_db_home(self):
|
||||
env = db.DBEnv()
|
||||
# check for crash fixed when db_home is used before open()
|
||||
assert env.db_home is None
|
||||
env.open(self.homeDir, db.DB_CREATE)
|
||||
assert self.homeDir == env.db_home
|
||||
|
||||
def test03_repr_closed_db(self):
|
||||
db = hashopen(self.filename)
|
||||
db.close()
|
||||
rp = repr(db)
|
||||
self.assertEquals(rp, "{}")
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
|
||||
def test_suite():
|
||||
return unittest.makeSuite(MiscTestCase)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(defaultTest='test_suite')
|
|
@ -1,75 +0,0 @@
|
|||
|
||||
import sys, os, string
|
||||
import pickle
|
||||
try:
|
||||
import cPickle
|
||||
except ImportError:
|
||||
cPickle = None
|
||||
import unittest
|
||||
import glob
|
||||
|
||||
try:
|
||||
# For Pythons w/distutils pybsddb
|
||||
from bsddb3 import db
|
||||
except ImportError, e:
|
||||
# For Python 2.3
|
||||
from bsddb import db
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
class pickleTestCase(unittest.TestCase):
|
||||
"""Verify that DBError can be pickled and unpickled"""
|
||||
db_home = 'db_home'
|
||||
db_name = 'test-dbobj.db'
|
||||
|
||||
def setUp(self):
|
||||
homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
|
||||
self.homeDir = homeDir
|
||||
try: os.mkdir(homeDir)
|
||||
except os.error: pass
|
||||
|
||||
def tearDown(self):
|
||||
if hasattr(self, 'db'):
|
||||
del self.db
|
||||
if hasattr(self, 'env'):
|
||||
del self.env
|
||||
files = glob.glob(os.path.join(self.homeDir, '*'))
|
||||
for file in files:
|
||||
os.remove(file)
|
||||
|
||||
def _base_test_pickle_DBError(self, pickle):
|
||||
self.env = db.DBEnv()
|
||||
self.env.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL)
|
||||
self.db = db.DB(self.env)
|
||||
self.db.open(self.db_name, db.DB_HASH, db.DB_CREATE)
|
||||
self.db.put('spam', 'eggs')
|
||||
assert self.db['spam'] == 'eggs'
|
||||
try:
|
||||
self.db.put('spam', 'ham', flags=db.DB_NOOVERWRITE)
|
||||
except db.DBError, egg:
|
||||
pickledEgg = pickle.dumps(egg)
|
||||
#print repr(pickledEgg)
|
||||
rottenEgg = pickle.loads(pickledEgg)
|
||||
if rottenEgg.args != egg.args or type(rottenEgg) != type(egg):
|
||||
raise Exception, (rottenEgg, '!=', egg)
|
||||
else:
|
||||
raise Exception, "where's my DBError exception?!?"
|
||||
|
||||
self.db.close()
|
||||
self.env.close()
|
||||
|
||||
def test01_pickle_DBError(self):
|
||||
self._base_test_pickle_DBError(pickle=pickle)
|
||||
|
||||
if cPickle:
|
||||
def test02_cPickle_DBError(self):
|
||||
self._base_test_pickle_DBError(pickle=cPickle)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
def test_suite():
|
||||
return unittest.makeSuite(pickleTestCase)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(defaultTest='test_suite')
|
|
@ -1,173 +0,0 @@
|
|||
"""
|
||||
TestCases for exercising a Queue DB.
|
||||
"""
|
||||
|
||||
import sys, os, string
|
||||
import tempfile
|
||||
from pprint import pprint
|
||||
import unittest
|
||||
|
||||
try:
|
||||
# For Pythons w/distutils pybsddb
|
||||
from bsddb3 import db
|
||||
except ImportError:
|
||||
# For Python 2.3
|
||||
from bsddb import db
|
||||
|
||||
from test_all import verbose
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
class SimpleQueueTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.filename = tempfile.mktemp()
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
os.remove(self.filename)
|
||||
except os.error:
|
||||
pass
|
||||
|
||||
|
||||
def test01_basic(self):
|
||||
# Basic Queue tests using the deprecated DBCursor.consume method.
|
||||
|
||||
if verbose:
|
||||
print '\n', '-=' * 30
|
||||
print "Running %s.test01_basic..." % self.__class__.__name__
|
||||
|
||||
d = db.DB()
|
||||
d.set_re_len(40) # Queues must be fixed length
|
||||
d.open(self.filename, db.DB_QUEUE, db.DB_CREATE)
|
||||
|
||||
if verbose:
|
||||
print "before appends" + '-' * 30
|
||||
pprint(d.stat())
|
||||
|
||||
for x in string.letters:
|
||||
d.append(x * 40)
|
||||
|
||||
assert len(d) == 52
|
||||
|
||||
d.put(100, "some more data")
|
||||
d.put(101, "and some more ")
|
||||
d.put(75, "out of order")
|
||||
d.put(1, "replacement data")
|
||||
|
||||
assert len(d) == 55
|
||||
|
||||
if verbose:
|
||||
print "before close" + '-' * 30
|
||||
pprint(d.stat())
|
||||
|
||||
d.close()
|
||||
del d
|
||||
d = db.DB()
|
||||
d.open(self.filename)
|
||||
|
||||
if verbose:
|
||||
print "after open" + '-' * 30
|
||||
pprint(d.stat())
|
||||
|
||||
d.append("one more")
|
||||
c = d.cursor()
|
||||
|
||||
if verbose:
|
||||
print "after append" + '-' * 30
|
||||
pprint(d.stat())
|
||||
|
||||
rec = c.consume()
|
||||
while rec:
|
||||
if verbose:
|
||||
print rec
|
||||
rec = c.consume()
|
||||
c.close()
|
||||
|
||||
if verbose:
|
||||
print "after consume loop" + '-' * 30
|
||||
pprint(d.stat())
|
||||
|
||||
assert len(d) == 0, \
|
||||
"if you see this message then you need to rebuild " \
|
||||
"BerkeleyDB 3.1.17 with the patch in patches/qam_stat.diff"
|
||||
|
||||
d.close()
|
||||
|
||||
|
||||
|
||||
def test02_basicPost32(self):
|
||||
# Basic Queue tests using the new DB.consume method in DB 3.2+
|
||||
# (No cursor needed)
|
||||
|
||||
if verbose:
|
||||
print '\n', '-=' * 30
|
||||
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.set_re_len(40) # Queues must be fixed length
|
||||
d.open(self.filename, db.DB_QUEUE, db.DB_CREATE)
|
||||
|
||||
if verbose:
|
||||
print "before appends" + '-' * 30
|
||||
pprint(d.stat())
|
||||
|
||||
for x in string.letters:
|
||||
d.append(x * 40)
|
||||
|
||||
assert len(d) == 52
|
||||
|
||||
d.put(100, "some more data")
|
||||
d.put(101, "and some more ")
|
||||
d.put(75, "out of order")
|
||||
d.put(1, "replacement data")
|
||||
|
||||
assert len(d) == 55
|
||||
|
||||
if verbose:
|
||||
print "before close" + '-' * 30
|
||||
pprint(d.stat())
|
||||
|
||||
d.close()
|
||||
del d
|
||||
d = db.DB()
|
||||
d.open(self.filename)
|
||||
#d.set_get_returns_none(true)
|
||||
|
||||
if verbose:
|
||||
print "after open" + '-' * 30
|
||||
pprint(d.stat())
|
||||
|
||||
d.append("one more")
|
||||
|
||||
if verbose:
|
||||
print "after append" + '-' * 30
|
||||
pprint(d.stat())
|
||||
|
||||
rec = d.consume()
|
||||
while rec:
|
||||
if verbose:
|
||||
print rec
|
||||
rec = d.consume()
|
||||
|
||||
if verbose:
|
||||
print "after consume loop" + '-' * 30
|
||||
pprint(d.stat())
|
||||
|
||||
d.close()
|
||||
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
def test_suite():
|
||||
return unittest.makeSuite(SimpleQueueTestCase)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(defaultTest='test_suite')
|
|
@ -1,295 +0,0 @@
|
|||
"""TestCases for exercising a Recno DB.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import errno
|
||||
import tempfile
|
||||
from pprint import pprint
|
||||
import unittest
|
||||
|
||||
from test_all import verbose
|
||||
|
||||
try:
|
||||
# For Pythons w/distutils pybsddb
|
||||
from bsddb3 import db
|
||||
except ImportError:
|
||||
# For Python 2.3
|
||||
from bsddb import db
|
||||
|
||||
letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
class SimpleRecnoTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.filename = tempfile.mktemp()
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
os.remove(self.filename)
|
||||
except OSError, e:
|
||||
if e.errno <> errno.EEXIST: raise
|
||||
|
||||
def test01_basic(self):
|
||||
d = db.DB()
|
||||
|
||||
get_returns_none = d.set_get_returns_none(2)
|
||||
d.set_get_returns_none(get_returns_none)
|
||||
|
||||
d.open(self.filename, db.DB_RECNO, db.DB_CREATE)
|
||||
|
||||
for x in letters:
|
||||
recno = d.append(x * 60)
|
||||
assert type(recno) == type(0)
|
||||
assert recno >= 1
|
||||
if verbose:
|
||||
print recno,
|
||||
|
||||
if verbose: print
|
||||
|
||||
stat = d.stat()
|
||||
if verbose:
|
||||
pprint(stat)
|
||||
|
||||
for recno in range(1, len(d)+1):
|
||||
data = d[recno]
|
||||
if verbose:
|
||||
print data
|
||||
|
||||
assert type(data) == type("")
|
||||
assert data == d.get(recno)
|
||||
|
||||
try:
|
||||
data = d[0] # This should raise a KeyError!?!?!
|
||||
except db.DBInvalidArgError, val:
|
||||
assert val[0] == db.EINVAL
|
||||
if verbose: print val
|
||||
else:
|
||||
self.fail("expected exception")
|
||||
|
||||
# test that has_key raises DB exceptions (fixed in pybsddb 4.3.2)
|
||||
try:
|
||||
d.has_key(0)
|
||||
except db.DBError, val:
|
||||
pass
|
||||
else:
|
||||
self.fail("has_key did not raise a proper exception")
|
||||
|
||||
try:
|
||||
data = d[100]
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
self.fail("expected exception")
|
||||
|
||||
try:
|
||||
data = d.get(100)
|
||||
except db.DBNotFoundError, val:
|
||||
if get_returns_none:
|
||||
self.fail("unexpected exception")
|
||||
else:
|
||||
assert data == None
|
||||
|
||||
keys = d.keys()
|
||||
if verbose:
|
||||
print keys
|
||||
assert type(keys) == type([])
|
||||
assert type(keys[0]) == type(123)
|
||||
assert len(keys) == len(d)
|
||||
|
||||
items = d.items()
|
||||
if verbose:
|
||||
pprint(items)
|
||||
assert type(items) == type([])
|
||||
assert type(items[0]) == type(())
|
||||
assert len(items[0]) == 2
|
||||
assert type(items[0][0]) == type(123)
|
||||
assert type(items[0][1]) == type("")
|
||||
assert len(items) == len(d)
|
||||
|
||||
assert d.has_key(25)
|
||||
|
||||
del d[25]
|
||||
assert not d.has_key(25)
|
||||
|
||||
d.delete(13)
|
||||
assert not d.has_key(13)
|
||||
|
||||
data = d.get_both(26, "z" * 60)
|
||||
assert data == "z" * 60
|
||||
if verbose:
|
||||
print data
|
||||
|
||||
fd = d.fd()
|
||||
if verbose:
|
||||
print fd
|
||||
|
||||
c = d.cursor()
|
||||
rec = c.first()
|
||||
while rec:
|
||||
if verbose:
|
||||
print rec
|
||||
rec = c.next()
|
||||
|
||||
c.set(50)
|
||||
rec = c.current()
|
||||
if verbose:
|
||||
print rec
|
||||
|
||||
c.put(-1, "a replacement record", db.DB_CURRENT)
|
||||
|
||||
c.set(50)
|
||||
rec = c.current()
|
||||
assert rec == (50, "a replacement record")
|
||||
if verbose:
|
||||
print rec
|
||||
|
||||
rec = c.set_range(30)
|
||||
if verbose:
|
||||
print rec
|
||||
|
||||
# test that non-existant key lookups work (and that
|
||||
# DBC_set_range doesn't have a memleak under valgrind)
|
||||
rec = c.set_range(999999)
|
||||
assert rec == None
|
||||
if verbose:
|
||||
print rec
|
||||
|
||||
c.close()
|
||||
d.close()
|
||||
|
||||
d = db.DB()
|
||||
d.open(self.filename)
|
||||
c = d.cursor()
|
||||
|
||||
# put a record beyond the consecutive end of the recno's
|
||||
d[100] = "way out there"
|
||||
assert d[100] == "way out there"
|
||||
|
||||
try:
|
||||
data = d[99]
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
self.fail("expected exception")
|
||||
|
||||
try:
|
||||
d.get(99)
|
||||
except db.DBKeyEmptyError, val:
|
||||
if get_returns_none:
|
||||
self.fail("unexpected DBKeyEmptyError exception")
|
||||
else:
|
||||
assert val[0] == db.DB_KEYEMPTY
|
||||
if verbose: print val
|
||||
else:
|
||||
if not get_returns_none:
|
||||
self.fail("expected exception")
|
||||
|
||||
rec = c.set(40)
|
||||
while rec:
|
||||
if verbose:
|
||||
print rec
|
||||
rec = c.next()
|
||||
|
||||
c.close()
|
||||
d.close()
|
||||
|
||||
def test02_WithSource(self):
|
||||
"""
|
||||
A Recno file that is given a "backing source file" is essentially a
|
||||
simple ASCII file. Normally each record is delimited by \n and so is
|
||||
just a line in the file, but you can set a different record delimiter
|
||||
if needed.
|
||||
"""
|
||||
source = os.path.join(os.path.dirname(sys.argv[0]),
|
||||
'db_home/test_recno.txt')
|
||||
if not os.path.isdir('db_home'):
|
||||
os.mkdir('db_home')
|
||||
f = open(source, 'w') # create the file
|
||||
f.close()
|
||||
|
||||
d = db.DB()
|
||||
# This is the default value, just checking if both int
|
||||
d.set_re_delim(0x0A)
|
||||
d.set_re_delim('\n') # and char can be used...
|
||||
d.set_re_source(source)
|
||||
d.open(self.filename, db.DB_RECNO, db.DB_CREATE)
|
||||
|
||||
data = "The quick brown fox jumped over the lazy dog".split()
|
||||
for datum in data:
|
||||
d.append(datum)
|
||||
d.sync()
|
||||
d.close()
|
||||
|
||||
# get the text from the backing source
|
||||
text = open(source, 'r').read()
|
||||
text = text.strip()
|
||||
if verbose:
|
||||
print text
|
||||
print data
|
||||
print text.split('\n')
|
||||
|
||||
assert text.split('\n') == data
|
||||
|
||||
# open as a DB again
|
||||
d = db.DB()
|
||||
d.set_re_source(source)
|
||||
d.open(self.filename, db.DB_RECNO)
|
||||
|
||||
d[3] = 'reddish-brown'
|
||||
d[8] = 'comatose'
|
||||
|
||||
d.sync()
|
||||
d.close()
|
||||
|
||||
text = open(source, 'r').read()
|
||||
text = text.strip()
|
||||
if verbose:
|
||||
print text
|
||||
print text.split('\n')
|
||||
|
||||
assert text.split('\n') == \
|
||||
"The quick reddish-brown fox jumped over the comatose dog".split()
|
||||
|
||||
def test03_FixedLength(self):
|
||||
d = db.DB()
|
||||
d.set_re_len(40) # fixed length records, 40 bytes long
|
||||
d.set_re_pad('-') # sets the pad character...
|
||||
d.set_re_pad(45) # ...test both int and char
|
||||
d.open(self.filename, db.DB_RECNO, db.DB_CREATE)
|
||||
|
||||
for x in letters:
|
||||
d.append(x * 35) # These will be padded
|
||||
|
||||
d.append('.' * 40) # this one will be exact
|
||||
|
||||
try: # this one will fail
|
||||
d.append('bad' * 20)
|
||||
except db.DBInvalidArgError, val:
|
||||
assert val[0] == db.EINVAL
|
||||
if verbose: print val
|
||||
else:
|
||||
self.fail("expected exception")
|
||||
|
||||
c = d.cursor()
|
||||
rec = c.first()
|
||||
while rec:
|
||||
if verbose:
|
||||
print rec
|
||||
rec = c.next()
|
||||
|
||||
c.close()
|
||||
d.close()
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
|
||||
def test_suite():
|
||||
return unittest.makeSuite(SimpleRecnoTestCase)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(defaultTest='test_suite')
|
|
@ -1,112 +0,0 @@
|
|||
import unittest
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
import glob
|
||||
|
||||
try:
|
||||
# For Pythons w/distutils pybsddb
|
||||
from bsddb3 import db
|
||||
except ImportError:
|
||||
from bsddb import db
|
||||
|
||||
from test_all import verbose
|
||||
|
||||
|
||||
class DBSequenceTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.int_32_max = 0x100000000
|
||||
self.homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
|
||||
try:
|
||||
os.mkdir(self.homeDir)
|
||||
except os.error:
|
||||
pass
|
||||
tempfile.tempdir = self.homeDir
|
||||
self.filename = os.path.split(tempfile.mktemp())[1]
|
||||
tempfile.tempdir = None
|
||||
|
||||
self.dbenv = db.DBEnv()
|
||||
self.dbenv.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL, 0666)
|
||||
self.d = db.DB(self.dbenv)
|
||||
self.d.open(self.filename, db.DB_BTREE, db.DB_CREATE, 0666)
|
||||
|
||||
def tearDown(self):
|
||||
if hasattr(self, 'seq'):
|
||||
self.seq.close()
|
||||
del self.seq
|
||||
if hasattr(self, 'd'):
|
||||
self.d.close()
|
||||
del self.d
|
||||
if hasattr(self, 'dbenv'):
|
||||
self.dbenv.close()
|
||||
del self.dbenv
|
||||
|
||||
files = glob.glob(os.path.join(self.homeDir, '*'))
|
||||
for file in files:
|
||||
os.remove(file)
|
||||
|
||||
def test_get(self):
|
||||
self.seq = db.DBSequence(self.d, flags=0)
|
||||
start_value = 10 * self.int_32_max
|
||||
self.assertEqual(0xA00000000, start_value)
|
||||
self.assertEquals(None, self.seq.init_value(start_value))
|
||||
self.assertEquals(None, self.seq.open(key='id', txn=None, flags=db.DB_CREATE))
|
||||
self.assertEquals(start_value, self.seq.get(5))
|
||||
self.assertEquals(start_value + 5, self.seq.get())
|
||||
|
||||
def test_remove(self):
|
||||
self.seq = db.DBSequence(self.d, flags=0)
|
||||
self.assertEquals(None, self.seq.open(key='foo', txn=None, flags=db.DB_CREATE))
|
||||
self.assertEquals(None, self.seq.remove(txn=None, flags=0))
|
||||
del self.seq
|
||||
|
||||
def test_get_key(self):
|
||||
self.seq = db.DBSequence(self.d, flags=0)
|
||||
key = 'foo'
|
||||
self.assertEquals(None, self.seq.open(key=key, txn=None, flags=db.DB_CREATE))
|
||||
self.assertEquals(key, self.seq.get_key())
|
||||
|
||||
def test_get_dbp(self):
|
||||
self.seq = db.DBSequence(self.d, flags=0)
|
||||
self.assertEquals(None, self.seq.open(key='foo', txn=None, flags=db.DB_CREATE))
|
||||
self.assertEquals(self.d, self.seq.get_dbp())
|
||||
|
||||
def test_cachesize(self):
|
||||
self.seq = db.DBSequence(self.d, flags=0)
|
||||
cashe_size = 10
|
||||
self.assertEquals(None, self.seq.set_cachesize(cashe_size))
|
||||
self.assertEquals(None, self.seq.open(key='foo', txn=None, flags=db.DB_CREATE))
|
||||
self.assertEquals(cashe_size, self.seq.get_cachesize())
|
||||
|
||||
def test_flags(self):
|
||||
self.seq = db.DBSequence(self.d, flags=0)
|
||||
flag = db.DB_SEQ_WRAP;
|
||||
self.assertEquals(None, self.seq.set_flags(flag))
|
||||
self.assertEquals(None, self.seq.open(key='foo', txn=None, flags=db.DB_CREATE))
|
||||
self.assertEquals(flag, self.seq.get_flags() & flag)
|
||||
|
||||
def test_range(self):
|
||||
self.seq = db.DBSequence(self.d, flags=0)
|
||||
seq_range = (10 * self.int_32_max, 11 * self.int_32_max - 1)
|
||||
self.assertEquals(None, self.seq.set_range(seq_range))
|
||||
self.seq.init_value(seq_range[0])
|
||||
self.assertEquals(None, self.seq.open(key='foo', txn=None, flags=db.DB_CREATE))
|
||||
self.assertEquals(seq_range, self.seq.get_range())
|
||||
|
||||
def test_stat(self):
|
||||
self.seq = db.DBSequence(self.d, flags=0)
|
||||
self.assertEquals(None, self.seq.open(key='foo', txn=None, flags=db.DB_CREATE))
|
||||
stat = self.seq.stat()
|
||||
for param in ('nowait', 'min', 'max', 'value', 'current',
|
||||
'flags', 'cache_size', 'last_value', 'wait'):
|
||||
self.assertTrue(param in stat, "parameter %s isn't in stat info" % param)
|
||||
|
||||
def test_suite():
|
||||
suite = unittest.TestSuite()
|
||||
if db.version() >= (4,3):
|
||||
suite.addTest(unittest.makeSuite(DBSequenceTest))
|
||||
return suite
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(defaultTest='test_suite')
|
|
@ -1,506 +0,0 @@
|
|||
"""TestCases for multi-threaded access to a DB.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import errno
|
||||
import shutil
|
||||
import tempfile
|
||||
from pprint import pprint
|
||||
from random import random
|
||||
|
||||
try:
|
||||
True, False
|
||||
except NameError:
|
||||
True = 1
|
||||
False = 0
|
||||
|
||||
DASH = '-'
|
||||
|
||||
try:
|
||||
from threading import Thread, currentThread
|
||||
have_threads = True
|
||||
except ImportError:
|
||||
have_threads = False
|
||||
|
||||
try:
|
||||
WindowsError
|
||||
except NameError:
|
||||
class WindowsError(Exception):
|
||||
pass
|
||||
|
||||
import unittest
|
||||
from test_all import verbose
|
||||
|
||||
try:
|
||||
# For Pythons w/distutils pybsddb
|
||||
from bsddb3 import db, dbutils
|
||||
except ImportError:
|
||||
# For Python 2.3
|
||||
from bsddb import db, dbutils
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
class BaseThreadedTestCase(unittest.TestCase):
|
||||
dbtype = db.DB_UNKNOWN # must be set in derived class
|
||||
dbopenflags = 0
|
||||
dbsetflags = 0
|
||||
envflags = 0
|
||||
|
||||
def setUp(self):
|
||||
if verbose:
|
||||
dbutils._deadlock_VerboseFile = sys.stdout
|
||||
|
||||
homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
|
||||
self.homeDir = homeDir
|
||||
try:
|
||||
os.mkdir(homeDir)
|
||||
except OSError, e:
|
||||
if e.errno <> errno.EEXIST: raise
|
||||
self.env = db.DBEnv()
|
||||
self.setEnvOpts()
|
||||
self.env.open(homeDir, self.envflags | db.DB_CREATE)
|
||||
|
||||
self.filename = self.__class__.__name__ + '.db'
|
||||
self.d = db.DB(self.env)
|
||||
if self.dbsetflags:
|
||||
self.d.set_flags(self.dbsetflags)
|
||||
self.d.open(self.filename, self.dbtype, self.dbopenflags|db.DB_CREATE)
|
||||
|
||||
def tearDown(self):
|
||||
self.d.close()
|
||||
self.env.close()
|
||||
shutil.rmtree(self.homeDir)
|
||||
|
||||
def setEnvOpts(self):
|
||||
pass
|
||||
|
||||
def makeData(self, key):
|
||||
return DASH.join([key] * 5)
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
|
||||
class ConcurrentDataStoreBase(BaseThreadedTestCase):
|
||||
dbopenflags = db.DB_THREAD
|
||||
envflags = db.DB_THREAD | db.DB_INIT_CDB | db.DB_INIT_MPOOL
|
||||
readers = 0 # derived class should set
|
||||
writers = 0
|
||||
records = 1000
|
||||
|
||||
def test01_1WriterMultiReaders(self):
|
||||
if verbose:
|
||||
print '\n', '-=' * 30
|
||||
print "Running %s.test01_1WriterMultiReaders..." % \
|
||||
self.__class__.__name__
|
||||
|
||||
threads = []
|
||||
for x in range(self.writers):
|
||||
wt = Thread(target = self.writerThread,
|
||||
args = (self.d, self.records, x),
|
||||
name = 'writer %d' % x,
|
||||
)#verbose = verbose)
|
||||
threads.append(wt)
|
||||
|
||||
for x in range(self.readers):
|
||||
rt = Thread(target = self.readerThread,
|
||||
args = (self.d, x),
|
||||
name = 'reader %d' % x,
|
||||
)#verbose = verbose)
|
||||
threads.append(rt)
|
||||
|
||||
for t in threads:
|
||||
t.start()
|
||||
for t in threads:
|
||||
t.join()
|
||||
|
||||
def writerThread(self, d, howMany, writerNum):
|
||||
#time.sleep(0.01 * writerNum + 0.01)
|
||||
name = currentThread().getName()
|
||||
start = howMany * writerNum
|
||||
stop = howMany * (writerNum + 1) - 1
|
||||
if verbose:
|
||||
print "%s: creating records %d - %d" % (name, start, stop)
|
||||
|
||||
for x in range(start, stop):
|
||||
key = '%04d' % x
|
||||
dbutils.DeadlockWrap(d.put, key, self.makeData(key),
|
||||
max_retries=12)
|
||||
if verbose and x % 100 == 0:
|
||||
print "%s: records %d - %d finished" % (name, start, x)
|
||||
|
||||
if verbose:
|
||||
print "%s: finished creating records" % name
|
||||
|
||||
## # Each write-cursor will be exclusive, the only one that can update the DB...
|
||||
## if verbose: print "%s: deleting a few records" % name
|
||||
## c = d.cursor(flags = db.DB_WRITECURSOR)
|
||||
## for x in range(10):
|
||||
## key = int(random() * howMany) + start
|
||||
## key = '%04d' % key
|
||||
## if d.has_key(key):
|
||||
## c.set(key)
|
||||
## c.delete()
|
||||
|
||||
## c.close()
|
||||
if verbose:
|
||||
print "%s: thread finished" % name
|
||||
|
||||
def readerThread(self, d, readerNum):
|
||||
time.sleep(0.01 * readerNum)
|
||||
name = currentThread().getName()
|
||||
|
||||
for loop in range(5):
|
||||
c = d.cursor()
|
||||
count = 0
|
||||
rec = c.first()
|
||||
while rec:
|
||||
count += 1
|
||||
key, data = rec
|
||||
self.assertEqual(self.makeData(key), data)
|
||||
rec = c.next()
|
||||
if verbose:
|
||||
print "%s: found %d records" % (name, count)
|
||||
c.close()
|
||||
time.sleep(0.05)
|
||||
|
||||
if verbose:
|
||||
print "%s: thread finished" % name
|
||||
|
||||
|
||||
class BTreeConcurrentDataStore(ConcurrentDataStoreBase):
|
||||
dbtype = db.DB_BTREE
|
||||
writers = 2
|
||||
readers = 10
|
||||
records = 1000
|
||||
|
||||
|
||||
class HashConcurrentDataStore(ConcurrentDataStoreBase):
|
||||
dbtype = db.DB_HASH
|
||||
writers = 2
|
||||
readers = 10
|
||||
records = 1000
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
class SimpleThreadedBase(BaseThreadedTestCase):
|
||||
dbopenflags = db.DB_THREAD
|
||||
envflags = db.DB_THREAD | db.DB_INIT_MPOOL | db.DB_INIT_LOCK
|
||||
readers = 5
|
||||
writers = 3
|
||||
records = 1000
|
||||
|
||||
def setEnvOpts(self):
|
||||
self.env.set_lk_detect(db.DB_LOCK_DEFAULT)
|
||||
|
||||
def test02_SimpleLocks(self):
|
||||
if verbose:
|
||||
print '\n', '-=' * 30
|
||||
print "Running %s.test02_SimpleLocks..." % self.__class__.__name__
|
||||
|
||||
threads = []
|
||||
for x in range(self.writers):
|
||||
wt = Thread(target = self.writerThread,
|
||||
args = (self.d, self.records, x),
|
||||
name = 'writer %d' % x,
|
||||
)#verbose = verbose)
|
||||
threads.append(wt)
|
||||
for x in range(self.readers):
|
||||
rt = Thread(target = self.readerThread,
|
||||
args = (self.d, x),
|
||||
name = 'reader %d' % x,
|
||||
)#verbose = verbose)
|
||||
threads.append(rt)
|
||||
|
||||
for t in threads:
|
||||
t.start()
|
||||
for t in threads:
|
||||
t.join()
|
||||
|
||||
def writerThread(self, d, howMany, writerNum):
|
||||
name = currentThread().getName()
|
||||
start = howMany * writerNum
|
||||
stop = howMany * (writerNum + 1) - 1
|
||||
if verbose:
|
||||
print "%s: creating records %d - %d" % (name, start, stop)
|
||||
|
||||
# create a bunch of records
|
||||
for x in xrange(start, stop):
|
||||
key = '%04d' % x
|
||||
dbutils.DeadlockWrap(d.put, key, self.makeData(key),
|
||||
max_retries=12)
|
||||
|
||||
if verbose and x % 100 == 0:
|
||||
print "%s: records %d - %d finished" % (name, start, x)
|
||||
|
||||
# do a bit or reading too
|
||||
if random() <= 0.05:
|
||||
for y in xrange(start, x):
|
||||
key = '%04d' % x
|
||||
data = dbutils.DeadlockWrap(d.get, key, max_retries=12)
|
||||
self.assertEqual(data, self.makeData(key))
|
||||
|
||||
# flush them
|
||||
try:
|
||||
dbutils.DeadlockWrap(d.sync, max_retries=12)
|
||||
except db.DBIncompleteError, val:
|
||||
if verbose:
|
||||
print "could not complete sync()..."
|
||||
|
||||
# read them back, deleting a few
|
||||
for x in xrange(start, stop):
|
||||
key = '%04d' % x
|
||||
data = dbutils.DeadlockWrap(d.get, key, max_retries=12)
|
||||
if verbose and x % 100 == 0:
|
||||
print "%s: fetched record (%s, %s)" % (name, key, data)
|
||||
self.assertEqual(data, self.makeData(key))
|
||||
if random() <= 0.10:
|
||||
dbutils.DeadlockWrap(d.delete, key, max_retries=12)
|
||||
if verbose:
|
||||
print "%s: deleted record %s" % (name, key)
|
||||
|
||||
if verbose:
|
||||
print "%s: thread finished" % name
|
||||
|
||||
def readerThread(self, d, readerNum):
|
||||
time.sleep(0.01 * readerNum)
|
||||
name = currentThread().getName()
|
||||
|
||||
for loop in range(5):
|
||||
c = d.cursor()
|
||||
count = 0
|
||||
rec = dbutils.DeadlockWrap(c.first, max_retries=10)
|
||||
while rec:
|
||||
count += 1
|
||||
key, data = rec
|
||||
self.assertEqual(self.makeData(key), data)
|
||||
rec = dbutils.DeadlockWrap(c.next, max_retries=10)
|
||||
if verbose:
|
||||
print "%s: found %d records" % (name, count)
|
||||
c.close()
|
||||
time.sleep(0.05)
|
||||
|
||||
if verbose:
|
||||
print "%s: thread finished" % name
|
||||
|
||||
|
||||
class BTreeSimpleThreaded(SimpleThreadedBase):
|
||||
dbtype = db.DB_BTREE
|
||||
|
||||
|
||||
class HashSimpleThreaded(SimpleThreadedBase):
|
||||
dbtype = db.DB_HASH
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
|
||||
class ThreadedTransactionsBase(BaseThreadedTestCase):
|
||||
dbopenflags = db.DB_THREAD | db.DB_AUTO_COMMIT
|
||||
envflags = (db.DB_THREAD |
|
||||
db.DB_INIT_MPOOL |
|
||||
db.DB_INIT_LOCK |
|
||||
db.DB_INIT_LOG |
|
||||
db.DB_INIT_TXN
|
||||
)
|
||||
readers = 0
|
||||
writers = 0
|
||||
records = 2000
|
||||
txnFlag = 0
|
||||
|
||||
def setEnvOpts(self):
|
||||
#self.env.set_lk_detect(db.DB_LOCK_DEFAULT)
|
||||
pass
|
||||
|
||||
def test03_ThreadedTransactions(self):
|
||||
if verbose:
|
||||
print '\n', '-=' * 30
|
||||
print "Running %s.test03_ThreadedTransactions..." % \
|
||||
self.__class__.__name__
|
||||
|
||||
threads = []
|
||||
for x in range(self.writers):
|
||||
wt = Thread(target = self.writerThread,
|
||||
args = (self.d, self.records, x),
|
||||
name = 'writer %d' % x,
|
||||
)#verbose = verbose)
|
||||
threads.append(wt)
|
||||
|
||||
for x in range(self.readers):
|
||||
rt = Thread(target = self.readerThread,
|
||||
args = (self.d, x),
|
||||
name = 'reader %d' % x,
|
||||
)#verbose = verbose)
|
||||
threads.append(rt)
|
||||
|
||||
dt = Thread(target = self.deadlockThread)
|
||||
dt.start()
|
||||
|
||||
for t in threads:
|
||||
t.start()
|
||||
for t in threads:
|
||||
t.join()
|
||||
|
||||
self.doLockDetect = False
|
||||
dt.join()
|
||||
|
||||
def doWrite(self, d, name, start, stop):
|
||||
finished = False
|
||||
while not finished:
|
||||
try:
|
||||
txn = self.env.txn_begin(None, self.txnFlag)
|
||||
for x in range(start, stop):
|
||||
key = '%04d' % x
|
||||
d.put(key, self.makeData(key), txn)
|
||||
if verbose and x % 100 == 0:
|
||||
print "%s: records %d - %d finished" % (name, start, x)
|
||||
txn.commit()
|
||||
finished = True
|
||||
except (db.DBLockDeadlockError, db.DBLockNotGrantedError), val:
|
||||
if verbose:
|
||||
print "%s: Aborting transaction (%s)" % (name, val[1])
|
||||
txn.abort()
|
||||
time.sleep(0.05)
|
||||
|
||||
def writerThread(self, d, howMany, writerNum):
|
||||
name = currentThread().getName()
|
||||
start = howMany * writerNum
|
||||
stop = howMany * (writerNum + 1) - 1
|
||||
if verbose:
|
||||
print "%s: creating records %d - %d" % (name, start, stop)
|
||||
|
||||
step = 100
|
||||
for x in range(start, stop, step):
|
||||
self.doWrite(d, name, x, min(stop, x+step))
|
||||
|
||||
if verbose:
|
||||
print "%s: finished creating records" % name
|
||||
if verbose:
|
||||
print "%s: deleting a few records" % name
|
||||
|
||||
finished = False
|
||||
while not finished:
|
||||
try:
|
||||
recs = []
|
||||
txn = self.env.txn_begin(None, self.txnFlag)
|
||||
for x in range(10):
|
||||
key = int(random() * howMany) + start
|
||||
key = '%04d' % key
|
||||
data = d.get(key, None, txn, db.DB_RMW)
|
||||
if data is not None:
|
||||
d.delete(key, txn)
|
||||
recs.append(key)
|
||||
txn.commit()
|
||||
finished = True
|
||||
if verbose:
|
||||
print "%s: deleted records %s" % (name, recs)
|
||||
except (db.DBLockDeadlockError, db.DBLockNotGrantedError), val:
|
||||
if verbose:
|
||||
print "%s: Aborting transaction (%s)" % (name, val[1])
|
||||
txn.abort()
|
||||
time.sleep(0.05)
|
||||
|
||||
if verbose:
|
||||
print "%s: thread finished" % name
|
||||
|
||||
def readerThread(self, d, readerNum):
|
||||
time.sleep(0.01 * readerNum + 0.05)
|
||||
name = currentThread().getName()
|
||||
|
||||
for loop in range(5):
|
||||
finished = False
|
||||
while not finished:
|
||||
try:
|
||||
txn = self.env.txn_begin(None, self.txnFlag)
|
||||
c = d.cursor(txn)
|
||||
count = 0
|
||||
rec = c.first()
|
||||
while rec:
|
||||
count += 1
|
||||
key, data = rec
|
||||
self.assertEqual(self.makeData(key), data)
|
||||
rec = c.next()
|
||||
if verbose: print "%s: found %d records" % (name, count)
|
||||
c.close()
|
||||
txn.commit()
|
||||
finished = True
|
||||
except (db.DBLockDeadlockError, db.DBLockNotGrantedError), val:
|
||||
if verbose:
|
||||
print "%s: Aborting transaction (%s)" % (name, val[1])
|
||||
c.close()
|
||||
txn.abort()
|
||||
time.sleep(0.05)
|
||||
|
||||
time.sleep(0.05)
|
||||
|
||||
if verbose:
|
||||
print "%s: thread finished" % name
|
||||
|
||||
def deadlockThread(self):
|
||||
self.doLockDetect = True
|
||||
while self.doLockDetect:
|
||||
time.sleep(0.5)
|
||||
try:
|
||||
aborted = self.env.lock_detect(
|
||||
db.DB_LOCK_RANDOM, db.DB_LOCK_CONFLICT)
|
||||
if verbose and aborted:
|
||||
print "deadlock: Aborted %d deadlocked transaction(s)" \
|
||||
% aborted
|
||||
except db.DBError:
|
||||
pass
|
||||
|
||||
|
||||
class BTreeThreadedTransactions(ThreadedTransactionsBase):
|
||||
dbtype = db.DB_BTREE
|
||||
writers = 3
|
||||
readers = 5
|
||||
records = 2000
|
||||
|
||||
class HashThreadedTransactions(ThreadedTransactionsBase):
|
||||
dbtype = db.DB_HASH
|
||||
writers = 1
|
||||
readers = 5
|
||||
records = 2000
|
||||
|
||||
class BTreeThreadedNoWaitTransactions(ThreadedTransactionsBase):
|
||||
dbtype = db.DB_BTREE
|
||||
writers = 3
|
||||
readers = 5
|
||||
records = 2000
|
||||
txnFlag = db.DB_TXN_NOWAIT
|
||||
|
||||
class HashThreadedNoWaitTransactions(ThreadedTransactionsBase):
|
||||
dbtype = db.DB_HASH
|
||||
writers = 1
|
||||
readers = 5
|
||||
records = 2000
|
||||
txnFlag = db.DB_TXN_NOWAIT
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
def test_suite():
|
||||
suite = unittest.TestSuite()
|
||||
|
||||
if have_threads:
|
||||
suite.addTest(unittest.makeSuite(BTreeConcurrentDataStore))
|
||||
suite.addTest(unittest.makeSuite(HashConcurrentDataStore))
|
||||
suite.addTest(unittest.makeSuite(BTreeSimpleThreaded))
|
||||
suite.addTest(unittest.makeSuite(HashSimpleThreaded))
|
||||
suite.addTest(unittest.makeSuite(BTreeThreadedTransactions))
|
||||
suite.addTest(unittest.makeSuite(HashThreadedTransactions))
|
||||
suite.addTest(unittest.makeSuite(BTreeThreadedNoWaitTransactions))
|
||||
suite.addTest(unittest.makeSuite(HashThreadedNoWaitTransactions))
|
||||
|
||||
else:
|
||||
print "Threads not available, skipping thread tests."
|
||||
|
||||
return suite
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(defaultTest='test_suite')
|
|
@ -1,202 +0,0 @@
|
|||
import glob, os, sys, unittest, getopt, time
|
||||
|
||||
use_resources = []
|
||||
|
||||
class ResourceDenied(Exception):
|
||||
"""Test skipped because it requested a disallowed resource.
|
||||
|
||||
This is raised when a test calls requires() for a resource that
|
||||
has not be enabled. Resources are defined by test modules.
|
||||
"""
|
||||
|
||||
def is_resource_enabled(resource):
|
||||
"""Test whether a resource is enabled.
|
||||
|
||||
If the caller's module is __main__ then automatically return True."""
|
||||
if sys._getframe().f_back.f_globals.get("__name__") == "__main__":
|
||||
return True
|
||||
result = use_resources is not None and \
|
||||
(resource in use_resources or "*" in use_resources)
|
||||
if not result:
|
||||
_unavail[resource] = None
|
||||
return result
|
||||
|
||||
_unavail = {}
|
||||
def requires(resource, msg=None):
|
||||
"""Raise ResourceDenied if the specified resource is not available.
|
||||
|
||||
If the caller's module is __main__ then automatically return True."""
|
||||
# see if the caller's module is __main__ - if so, treat as if
|
||||
# the resource was set
|
||||
if sys._getframe().f_back.f_globals.get("__name__") == "__main__":
|
||||
return
|
||||
if not is_resource_enabled(resource):
|
||||
if msg is None:
|
||||
msg = "Use of the `%s' resource not enabled" % resource
|
||||
raise ResourceDenied(msg)
|
||||
|
||||
def find_package_modules(package, mask):
|
||||
import fnmatch
|
||||
if hasattr(package, "__loader__"):
|
||||
path = package.__name__.replace(".", os.path.sep)
|
||||
mask = os.path.join(path, mask)
|
||||
for fnm in package.__loader__._files.iterkeys():
|
||||
if fnmatch.fnmatchcase(fnm, mask):
|
||||
yield os.path.splitext(fnm)[0].replace(os.path.sep, ".")
|
||||
else:
|
||||
path = package.__path__[0]
|
||||
for fnm in os.listdir(path):
|
||||
if fnmatch.fnmatchcase(fnm, mask):
|
||||
yield "%s.%s" % (package.__name__, os.path.splitext(fnm)[0])
|
||||
|
||||
def get_tests(package, mask, verbosity):
|
||||
"""Return a list of skipped test modules, and a list of test cases."""
|
||||
tests = []
|
||||
skipped = []
|
||||
for modname in find_package_modules(package, mask):
|
||||
try:
|
||||
mod = __import__(modname, globals(), locals(), ['*'])
|
||||
except ResourceDenied, detail:
|
||||
skipped.append(modname)
|
||||
if verbosity > 1:
|
||||
print >> sys.stderr, "Skipped %s: %s" % (modname, detail)
|
||||
continue
|
||||
except Exception, detail:
|
||||
print >> sys.stderr, "Warning: could not import %s: %s" % (modname, detail)
|
||||
continue
|
||||
for name in dir(mod):
|
||||
if name.startswith("_"):
|
||||
continue
|
||||
o = getattr(mod, name)
|
||||
if type(o) is type(unittest.TestCase) and issubclass(o, unittest.TestCase):
|
||||
tests.append(o)
|
||||
return skipped, tests
|
||||
|
||||
def usage():
|
||||
print __doc__
|
||||
return 1
|
||||
|
||||
def test_with_refcounts(runner, verbosity, testcase):
|
||||
"""Run testcase several times, tracking reference counts."""
|
||||
import gc
|
||||
import ctypes
|
||||
ptc = ctypes._pointer_type_cache.copy()
|
||||
cfc = ctypes._c_functype_cache.copy()
|
||||
wfc = ctypes._win_functype_cache.copy()
|
||||
|
||||
# when searching for refcount leaks, we have to manually reset any
|
||||
# caches that ctypes has.
|
||||
def cleanup():
|
||||
ctypes._pointer_type_cache = ptc.copy()
|
||||
ctypes._c_functype_cache = cfc.copy()
|
||||
ctypes._win_functype_cache = wfc.copy()
|
||||
gc.collect()
|
||||
|
||||
test = unittest.makeSuite(testcase)
|
||||
for i in range(5):
|
||||
rc = sys.gettotalrefcount()
|
||||
runner.run(test)
|
||||
cleanup()
|
||||
COUNT = 5
|
||||
refcounts = [None] * COUNT
|
||||
for i in range(COUNT):
|
||||
rc = sys.gettotalrefcount()
|
||||
runner.run(test)
|
||||
cleanup()
|
||||
refcounts[i] = sys.gettotalrefcount() - rc
|
||||
if filter(None, refcounts):
|
||||
print "%s leaks:\n\t" % testcase, refcounts
|
||||
elif verbosity:
|
||||
print "%s: ok." % testcase
|
||||
|
||||
class TestRunner(unittest.TextTestRunner):
|
||||
def run(self, test, skipped):
|
||||
"Run the given test case or test suite."
|
||||
# Same as unittest.TextTestRunner.run, except that it reports
|
||||
# skipped tests.
|
||||
result = self._makeResult()
|
||||
startTime = time.time()
|
||||
test(result)
|
||||
stopTime = time.time()
|
||||
timeTaken = stopTime - startTime
|
||||
result.printErrors()
|
||||
self.stream.writeln(result.separator2)
|
||||
run = result.testsRun
|
||||
if _unavail: #skipped:
|
||||
requested = _unavail.keys()
|
||||
requested.sort()
|
||||
self.stream.writeln("Ran %d test%s in %.3fs (%s module%s skipped)" %
|
||||
(run, run != 1 and "s" or "", timeTaken,
|
||||
len(skipped),
|
||||
len(skipped) != 1 and "s" or ""))
|
||||
self.stream.writeln("Unavailable resources: %s" % ", ".join(requested))
|
||||
else:
|
||||
self.stream.writeln("Ran %d test%s in %.3fs" %
|
||||
(run, run != 1 and "s" or "", timeTaken))
|
||||
self.stream.writeln()
|
||||
if not result.wasSuccessful():
|
||||
self.stream.write("FAILED (")
|
||||
failed, errored = map(len, (result.failures, result.errors))
|
||||
if failed:
|
||||
self.stream.write("failures=%d" % failed)
|
||||
if errored:
|
||||
if failed: self.stream.write(", ")
|
||||
self.stream.write("errors=%d" % errored)
|
||||
self.stream.writeln(")")
|
||||
else:
|
||||
self.stream.writeln("OK")
|
||||
return result
|
||||
|
||||
|
||||
def main(*packages):
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "rqvu:")
|
||||
except getopt.error:
|
||||
return usage()
|
||||
|
||||
verbosity = 1
|
||||
search_leaks = False
|
||||
for flag, value in opts:
|
||||
if flag == "-q":
|
||||
verbosity -= 1
|
||||
elif flag == "-v":
|
||||
verbosity += 1
|
||||
elif flag == "-r":
|
||||
try:
|
||||
sys.gettotalrefcount
|
||||
except AttributeError:
|
||||
print >> sys.stderr, "-r flag requires Python debug build"
|
||||
return -1
|
||||
search_leaks = True
|
||||
elif flag == "-u":
|
||||
use_resources.extend(value.split(","))
|
||||
|
||||
mask = "test_*.py"
|
||||
if args:
|
||||
mask = args[0]
|
||||
|
||||
for package in packages:
|
||||
run_tests(package, mask, verbosity, search_leaks)
|
||||
|
||||
|
||||
def run_tests(package, mask, verbosity, search_leaks):
|
||||
skipped, testcases = get_tests(package, mask, verbosity)
|
||||
runner = TestRunner(verbosity=verbosity)
|
||||
|
||||
suites = [unittest.makeSuite(o) for o in testcases]
|
||||
suite = unittest.TestSuite(suites)
|
||||
result = runner.run(suite, skipped)
|
||||
|
||||
if search_leaks:
|
||||
# hunt for refcount leaks
|
||||
runner = BasicTestRunner()
|
||||
for t in testcases:
|
||||
test_with_refcounts(runner, verbosity, t)
|
||||
|
||||
return bool(result.errors)
|
||||
|
||||
class BasicTestRunner:
|
||||
def run(self, test):
|
||||
result = unittest.TestResult()
|
||||
test(result)
|
||||
return result
|
|
@ -1,17 +0,0 @@
|
|||
"""Usage: runtests.py [-q] [-r] [-v] [-u resources] [mask]
|
||||
|
||||
Run all tests found in this directory, and print a summary of the results.
|
||||
Command line flags:
|
||||
-q quiet mode: don't prnt anything while the tests are running
|
||||
-r run tests repeatedly, look for refcount leaks
|
||||
-u<resources>
|
||||
Add resources to the lits of allowed resources. '*' allows all
|
||||
resources.
|
||||
-v verbose mode: print the test currently executed
|
||||
mask mask to select filenames containing testcases, wildcards allowed
|
||||
"""
|
||||
import sys
|
||||
import ctypes.test
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(ctypes.test.main(ctypes.test))
|
|
@ -1,60 +0,0 @@
|
|||
import unittest
|
||||
from ctypes import *
|
||||
|
||||
class AnonTest(unittest.TestCase):
|
||||
|
||||
def test_anon(self):
|
||||
class ANON(Union):
|
||||
_fields_ = [("a", c_int),
|
||||
("b", c_int)]
|
||||
|
||||
class Y(Structure):
|
||||
_fields_ = [("x", c_int),
|
||||
("_", ANON),
|
||||
("y", c_int)]
|
||||
_anonymous_ = ["_"]
|
||||
|
||||
self.failUnlessEqual(Y.a.offset, sizeof(c_int))
|
||||
self.failUnlessEqual(Y.b.offset, sizeof(c_int))
|
||||
|
||||
self.failUnlessEqual(ANON.a.offset, 0)
|
||||
self.failUnlessEqual(ANON.b.offset, 0)
|
||||
|
||||
def test_anon_nonseq(self):
|
||||
# TypeError: _anonymous_ must be a sequence
|
||||
self.failUnlessRaises(TypeError,
|
||||
lambda: type(Structure)("Name",
|
||||
(Structure,),
|
||||
{"_fields_": [], "_anonymous_": 42}))
|
||||
|
||||
def test_anon_nonmember(self):
|
||||
# AttributeError: type object 'Name' has no attribute 'x'
|
||||
self.failUnlessRaises(AttributeError,
|
||||
lambda: type(Structure)("Name",
|
||||
(Structure,),
|
||||
{"_fields_": [],
|
||||
"_anonymous_": ["x"]}))
|
||||
|
||||
def test_nested(self):
|
||||
class ANON_S(Structure):
|
||||
_fields_ = [("a", c_int)]
|
||||
|
||||
class ANON_U(Union):
|
||||
_fields_ = [("_", ANON_S),
|
||||
("b", c_int)]
|
||||
_anonymous_ = ["_"]
|
||||
|
||||
class Y(Structure):
|
||||
_fields_ = [("x", c_int),
|
||||
("_", ANON_U),
|
||||
("y", c_int)]
|
||||
_anonymous_ = ["_"]
|
||||
|
||||
self.failUnlessEqual(Y.x.offset, 0)
|
||||
self.failUnlessEqual(Y.a.offset, sizeof(c_int))
|
||||
self.failUnlessEqual(Y.b.offset, sizeof(c_int))
|
||||
self.failUnlessEqual(Y._.offset, sizeof(c_int))
|
||||
self.failUnlessEqual(Y.y.offset, sizeof(c_int) * 2)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
|
@ -1,64 +0,0 @@
|
|||
import unittest
|
||||
from ctypes import *
|
||||
from binascii import hexlify
|
||||
import re
|
||||
|
||||
def dump(obj):
|
||||
# helper function to dump memory contents in hex, with a hyphen
|
||||
# between the bytes.
|
||||
h = hexlify(buffer(obj))
|
||||
return re.sub(r"(..)", r"\1-", h)[:-1]
|
||||
|
||||
|
||||
class Value(Structure):
|
||||
_fields_ = [("val", c_byte)]
|
||||
|
||||
class Container(Structure):
|
||||
_fields_ = [("pvalues", POINTER(Value))]
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def test(self):
|
||||
# create an array of 4 values
|
||||
val_array = (Value * 4)()
|
||||
|
||||
# create a container, which holds a pointer to the pvalues array.
|
||||
c = Container()
|
||||
c.pvalues = val_array
|
||||
|
||||
# memory contains 4 NUL bytes now, that's correct
|
||||
self.failUnlessEqual("00-00-00-00", dump(val_array))
|
||||
|
||||
# set the values of the array through the pointer:
|
||||
for i in range(4):
|
||||
c.pvalues[i].val = i + 1
|
||||
|
||||
values = [c.pvalues[i].val for i in range(4)]
|
||||
|
||||
# These are the expected results: here s the bug!
|
||||
self.failUnlessEqual(
|
||||
(values, dump(val_array)),
|
||||
([1, 2, 3, 4], "01-02-03-04")
|
||||
)
|
||||
|
||||
def test_2(self):
|
||||
|
||||
val_array = (Value * 4)()
|
||||
|
||||
# memory contains 4 NUL bytes now, that's correct
|
||||
self.failUnlessEqual("00-00-00-00", dump(val_array))
|
||||
|
||||
ptr = cast(val_array, POINTER(Value))
|
||||
# set the values of the array through the pointer:
|
||||
for i in range(4):
|
||||
ptr[i].val = i + 1
|
||||
|
||||
values = [ptr[i].val for i in range(4)]
|
||||
|
||||
# These are the expected results: here s the bug!
|
||||
self.failUnlessEqual(
|
||||
(values, dump(val_array)),
|
||||
([1, 2, 3, 4], "01-02-03-04")
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
|
@ -1,112 +0,0 @@
|
|||
import unittest
|
||||
from ctypes import *
|
||||
|
||||
formats = "bBhHiIlLqQfd"
|
||||
|
||||
formats = c_byte, c_ubyte, c_short, c_ushort, c_int, c_uint, \
|
||||
c_long, c_ulonglong, c_float, c_double
|
||||
|
||||
class ArrayTestCase(unittest.TestCase):
|
||||
def test_simple(self):
|
||||
# create classes holding simple numeric types, and check
|
||||
# various properties.
|
||||
|
||||
init = range(15, 25)
|
||||
|
||||
for fmt in formats:
|
||||
alen = len(init)
|
||||
int_array = ARRAY(fmt, alen)
|
||||
|
||||
ia = int_array(*init)
|
||||
# length of instance ok?
|
||||
self.failUnlessEqual(len(ia), alen)
|
||||
|
||||
# slot values ok?
|
||||
values = [ia[i] for i in range(len(init))]
|
||||
self.failUnlessEqual(values, init)
|
||||
|
||||
# change the items
|
||||
from operator import setitem
|
||||
new_values = range(42, 42+alen)
|
||||
[setitem(ia, n, new_values[n]) for n in range(alen)]
|
||||
values = [ia[i] for i in range(len(init))]
|
||||
self.failUnlessEqual(values, new_values)
|
||||
|
||||
# are the items initialized to 0?
|
||||
ia = int_array()
|
||||
values = [ia[i] for i in range(len(init))]
|
||||
self.failUnlessEqual(values, [0] * len(init))
|
||||
|
||||
# Too many in itializers should be caught
|
||||
self.assertRaises(IndexError, int_array, *range(alen*2))
|
||||
|
||||
CharArray = ARRAY(c_char, 3)
|
||||
|
||||
ca = CharArray("a", "b", "c")
|
||||
|
||||
# Should this work? It doesn't:
|
||||
# CharArray("abc")
|
||||
self.assertRaises(TypeError, CharArray, "abc")
|
||||
|
||||
self.failUnlessEqual(ca[0], "a")
|
||||
self.failUnlessEqual(ca[1], "b")
|
||||
self.failUnlessEqual(ca[2], "c")
|
||||
self.failUnlessEqual(ca[-3], "a")
|
||||
self.failUnlessEqual(ca[-2], "b")
|
||||
self.failUnlessEqual(ca[-1], "c")
|
||||
|
||||
self.failUnlessEqual(len(ca), 3)
|
||||
|
||||
# slicing is now supported, but not extended slicing (3-argument)!
|
||||
from operator import getslice, delitem
|
||||
self.assertRaises(TypeError, getslice, ca, 0, 1, -1)
|
||||
|
||||
# cannot delete items
|
||||
self.assertRaises(TypeError, delitem, ca, 0)
|
||||
|
||||
def test_numeric_arrays(self):
|
||||
|
||||
alen = 5
|
||||
|
||||
numarray = ARRAY(c_int, alen)
|
||||
|
||||
na = numarray()
|
||||
values = [na[i] for i in range(alen)]
|
||||
self.failUnlessEqual(values, [0] * alen)
|
||||
|
||||
na = numarray(*[c_int()] * alen)
|
||||
values = [na[i] for i in range(alen)]
|
||||
self.failUnlessEqual(values, [0]*alen)
|
||||
|
||||
na = numarray(1, 2, 3, 4, 5)
|
||||
values = [i for i in na]
|
||||
self.failUnlessEqual(values, [1, 2, 3, 4, 5])
|
||||
|
||||
na = numarray(*map(c_int, (1, 2, 3, 4, 5)))
|
||||
values = [i for i in na]
|
||||
self.failUnlessEqual(values, [1, 2, 3, 4, 5])
|
||||
|
||||
def test_classcache(self):
|
||||
self.failUnless(not ARRAY(c_int, 3) is ARRAY(c_int, 4))
|
||||
self.failUnless(ARRAY(c_int, 3) is ARRAY(c_int, 3))
|
||||
|
||||
def test_from_address(self):
|
||||
# Failed with 0.9.8, reported by JUrner
|
||||
p = create_string_buffer("foo")
|
||||
sz = (c_char * 3).from_address(addressof(p))
|
||||
self.failUnlessEqual(sz[:], "foo")
|
||||
self.failUnlessEqual(sz.value, "foo")
|
||||
|
||||
try:
|
||||
create_unicode_buffer
|
||||
except NameError:
|
||||
pass
|
||||
else:
|
||||
def test_from_addressW(self):
|
||||
p = create_unicode_buffer("foo")
|
||||
sz = (c_wchar * 3).from_address(addressof(p))
|
||||
self.failUnlessEqual(sz[:], "foo")
|
||||
self.failUnlessEqual(sz.value, "foo")
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -1,215 +0,0 @@
|
|||
import unittest
|
||||
from ctypes import *
|
||||
import _ctypes_test
|
||||
|
||||
dll = CDLL(_ctypes_test.__file__)
|
||||
|
||||
try:
|
||||
CALLBACK_FUNCTYPE = WINFUNCTYPE
|
||||
except NameError:
|
||||
# fake to enable this test on Linux
|
||||
CALLBACK_FUNCTYPE = CFUNCTYPE
|
||||
|
||||
class POINT(Structure):
|
||||
_fields_ = [("x", c_int), ("y", c_int)]
|
||||
|
||||
class BasicWrapTestCase(unittest.TestCase):
|
||||
def wrap(self, param):
|
||||
return param
|
||||
|
||||
def test_wchar_parm(self):
|
||||
try:
|
||||
c_wchar
|
||||
except NameError:
|
||||
return
|
||||
f = dll._testfunc_i_bhilfd
|
||||
f.argtypes = [c_byte, c_wchar, c_int, c_long, c_float, c_double]
|
||||
result = f(self.wrap(1), self.wrap(u"x"), self.wrap(3), self.wrap(4), self.wrap(5.0), self.wrap(6.0))
|
||||
self.failUnlessEqual(result, 139)
|
||||
self.failUnless(type(result), int)
|
||||
|
||||
def test_pointers(self):
|
||||
f = dll._testfunc_p_p
|
||||
f.restype = POINTER(c_int)
|
||||
f.argtypes = [POINTER(c_int)]
|
||||
|
||||
# This only works if the value c_int(42) passed to the
|
||||
# function is still alive while the pointer (the result) is
|
||||
# used.
|
||||
|
||||
v = c_int(42)
|
||||
|
||||
self.failUnlessEqual(pointer(v).contents.value, 42)
|
||||
result = f(self.wrap(pointer(v)))
|
||||
self.failUnlessEqual(type(result), POINTER(c_int))
|
||||
self.failUnlessEqual(result.contents.value, 42)
|
||||
|
||||
# This on works...
|
||||
result = f(self.wrap(pointer(v)))
|
||||
self.failUnlessEqual(result.contents.value, v.value)
|
||||
|
||||
p = pointer(c_int(99))
|
||||
result = f(self.wrap(p))
|
||||
self.failUnlessEqual(result.contents.value, 99)
|
||||
|
||||
def test_shorts(self):
|
||||
f = dll._testfunc_callback_i_if
|
||||
|
||||
args = []
|
||||
expected = [262144, 131072, 65536, 32768, 16384, 8192, 4096, 2048,
|
||||
1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1]
|
||||
|
||||
def callback(v):
|
||||
args.append(v)
|
||||
return v
|
||||
|
||||
CallBack = CFUNCTYPE(c_int, c_int)
|
||||
|
||||
cb = CallBack(callback)
|
||||
f(self.wrap(2**18), self.wrap(cb))
|
||||
self.failUnlessEqual(args, expected)
|
||||
|
||||
################################################################
|
||||
|
||||
def test_callbacks(self):
|
||||
f = dll._testfunc_callback_i_if
|
||||
f.restype = c_int
|
||||
|
||||
MyCallback = CFUNCTYPE(c_int, c_int)
|
||||
|
||||
def callback(value):
|
||||
#print "called back with", value
|
||||
return value
|
||||
|
||||
cb = MyCallback(callback)
|
||||
|
||||
result = f(self.wrap(-10), self.wrap(cb))
|
||||
self.failUnlessEqual(result, -18)
|
||||
|
||||
# test with prototype
|
||||
f.argtypes = [c_int, MyCallback]
|
||||
cb = MyCallback(callback)
|
||||
|
||||
result = f(self.wrap(-10), self.wrap(cb))
|
||||
self.failUnlessEqual(result, -18)
|
||||
|
||||
result = f(self.wrap(-10), self.wrap(cb))
|
||||
self.failUnlessEqual(result, -18)
|
||||
|
||||
AnotherCallback = CALLBACK_FUNCTYPE(c_int, c_int, c_int, c_int, c_int)
|
||||
|
||||
# check that the prototype works: we call f with wrong
|
||||
# argument types
|
||||
cb = AnotherCallback(callback)
|
||||
self.assertRaises(ArgumentError, f, self.wrap(-10), self.wrap(cb))
|
||||
|
||||
def test_callbacks_2(self):
|
||||
# Can also use simple datatypes as argument type specifiers
|
||||
# for the callback function.
|
||||
# In this case the call receives an instance of that type
|
||||
f = dll._testfunc_callback_i_if
|
||||
f.restype = c_int
|
||||
|
||||
MyCallback = CFUNCTYPE(c_int, c_int)
|
||||
|
||||
f.argtypes = [c_int, MyCallback]
|
||||
|
||||
def callback(value):
|
||||
#print "called back with", value
|
||||
self.failUnlessEqual(type(value), int)
|
||||
return value
|
||||
|
||||
cb = MyCallback(callback)
|
||||
result = f(self.wrap(-10), self.wrap(cb))
|
||||
self.failUnlessEqual(result, -18)
|
||||
|
||||
def test_longlong_callbacks(self):
|
||||
|
||||
f = dll._testfunc_callback_q_qf
|
||||
f.restype = c_longlong
|
||||
|
||||
MyCallback = CFUNCTYPE(c_longlong, c_longlong)
|
||||
|
||||
f.argtypes = [c_longlong, MyCallback]
|
||||
|
||||
def callback(value):
|
||||
self.failUnless(isinstance(value, (int, long)))
|
||||
return value & 0x7FFFFFFF
|
||||
|
||||
cb = MyCallback(callback)
|
||||
|
||||
self.failUnlessEqual(13577625587, int(f(self.wrap(1000000000000), self.wrap(cb))))
|
||||
|
||||
def test_byval(self):
|
||||
# without prototype
|
||||
ptin = POINT(1, 2)
|
||||
ptout = POINT()
|
||||
# EXPORT int _testfunc_byval(point in, point *pout)
|
||||
result = dll._testfunc_byval(ptin, byref(ptout))
|
||||
got = result, ptout.x, ptout.y
|
||||
expected = 3, 1, 2
|
||||
self.failUnlessEqual(got, expected)
|
||||
|
||||
# with prototype
|
||||
ptin = POINT(101, 102)
|
||||
ptout = POINT()
|
||||
dll._testfunc_byval.argtypes = (POINT, POINTER(POINT))
|
||||
dll._testfunc_byval.restype = c_int
|
||||
result = dll._testfunc_byval(self.wrap(ptin), byref(ptout))
|
||||
got = result, ptout.x, ptout.y
|
||||
expected = 203, 101, 102
|
||||
self.failUnlessEqual(got, expected)
|
||||
|
||||
def test_struct_return_2H(self):
|
||||
class S2H(Structure):
|
||||
_fields_ = [("x", c_short),
|
||||
("y", c_short)]
|
||||
dll.ret_2h_func.restype = S2H
|
||||
dll.ret_2h_func.argtypes = [S2H]
|
||||
inp = S2H(99, 88)
|
||||
s2h = dll.ret_2h_func(self.wrap(inp))
|
||||
self.failUnlessEqual((s2h.x, s2h.y), (99*2, 88*3))
|
||||
|
||||
def test_struct_return_8H(self):
|
||||
class S8I(Structure):
|
||||
_fields_ = [("a", c_int),
|
||||
("b", c_int),
|
||||
("c", c_int),
|
||||
("d", c_int),
|
||||
("e", c_int),
|
||||
("f", c_int),
|
||||
("g", c_int),
|
||||
("h", c_int)]
|
||||
dll.ret_8i_func.restype = S8I
|
||||
dll.ret_8i_func.argtypes = [S8I]
|
||||
inp = S8I(9, 8, 7, 6, 5, 4, 3, 2)
|
||||
s8i = dll.ret_8i_func(self.wrap(inp))
|
||||
self.failUnlessEqual((s8i.a, s8i.b, s8i.c, s8i.d, s8i.e, s8i.f, s8i.g, s8i.h),
|
||||
(9*2, 8*3, 7*4, 6*5, 5*6, 4*7, 3*8, 2*9))
|
||||
|
||||
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
class AsParamWrapper(object):
|
||||
def __init__(self, param):
|
||||
self._as_parameter_ = param
|
||||
|
||||
class AsParamWrapperTestCase(BasicWrapTestCase):
|
||||
wrap = AsParamWrapper
|
||||
|
||||
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
class AsParamPropertyWrapper(object):
|
||||
def __init__(self, param):
|
||||
self._param = param
|
||||
|
||||
def getParameter(self):
|
||||
return self._param
|
||||
_as_parameter_ = property(getParameter)
|
||||
|
||||
class AsParamPropertyWrapperTestCase(BasicWrapTestCase):
|
||||
wrap = AsParamPropertyWrapper
|
||||
|
||||
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -1,228 +0,0 @@
|
|||
from ctypes import *
|
||||
import unittest
|
||||
import os
|
||||
|
||||
import ctypes
|
||||
import _ctypes_test
|
||||
|
||||
class BITS(Structure):
|
||||
_fields_ = [("A", c_int, 1),
|
||||
("B", c_int, 2),
|
||||
("C", c_int, 3),
|
||||
("D", c_int, 4),
|
||||
("E", c_int, 5),
|
||||
("F", c_int, 6),
|
||||
("G", c_int, 7),
|
||||
("H", c_int, 8),
|
||||
("I", c_int, 9),
|
||||
|
||||
("M", c_short, 1),
|
||||
("N", c_short, 2),
|
||||
("O", c_short, 3),
|
||||
("P", c_short, 4),
|
||||
("Q", c_short, 5),
|
||||
("R", c_short, 6),
|
||||
("S", c_short, 7)]
|
||||
|
||||
func = CDLL(_ctypes_test.__file__).unpack_bitfields
|
||||
func.argtypes = POINTER(BITS), c_char
|
||||
|
||||
##for n in "ABCDEFGHIMNOPQRS":
|
||||
## print n, hex(getattr(BITS, n).size), getattr(BITS, n).offset
|
||||
|
||||
class C_Test(unittest.TestCase):
|
||||
|
||||
def test_ints(self):
|
||||
for i in range(512):
|
||||
for name in "ABCDEFGHI":
|
||||
b = BITS()
|
||||
setattr(b, name, i)
|
||||
self.failUnlessEqual((name, i, getattr(b, name)), (name, i, func(byref(b), name)))
|
||||
|
||||
def test_shorts(self):
|
||||
for i in range(256):
|
||||
for name in "MNOPQRS":
|
||||
b = BITS()
|
||||
setattr(b, name, i)
|
||||
self.failUnlessEqual((name, i, getattr(b, name)), (name, i, func(byref(b), name)))
|
||||
|
||||
signed_int_types = (c_byte, c_short, c_int, c_long, c_longlong)
|
||||
unsigned_int_types = (c_ubyte, c_ushort, c_uint, c_ulong, c_ulonglong)
|
||||
int_types = unsigned_int_types + signed_int_types
|
||||
|
||||
class BitFieldTest(unittest.TestCase):
|
||||
|
||||
def test_longlong(self):
|
||||
class X(Structure):
|
||||
_fields_ = [("a", c_longlong, 1),
|
||||
("b", c_longlong, 62),
|
||||
("c", c_longlong, 1)]
|
||||
|
||||
self.failUnlessEqual(sizeof(X), sizeof(c_longlong))
|
||||
x = X()
|
||||
x.a, x.b, x.c = -1, 7, -1
|
||||
self.failUnlessEqual((x.a, x.b, x.c), (-1, 7, -1))
|
||||
|
||||
def test_ulonglong(self):
|
||||
class X(Structure):
|
||||
_fields_ = [("a", c_ulonglong, 1),
|
||||
("b", c_ulonglong, 62),
|
||||
("c", c_ulonglong, 1)]
|
||||
|
||||
self.failUnlessEqual(sizeof(X), sizeof(c_longlong))
|
||||
x = X()
|
||||
self.failUnlessEqual((x.a, x.b, x.c), (0, 0, 0))
|
||||
x.a, x.b, x.c = 7, 7, 7
|
||||
self.failUnlessEqual((x.a, x.b, x.c), (1, 7, 1))
|
||||
|
||||
def test_signed(self):
|
||||
for c_typ in signed_int_types:
|
||||
class X(Structure):
|
||||
_fields_ = [("dummy", c_typ),
|
||||
("a", c_typ, 3),
|
||||
("b", c_typ, 3),
|
||||
("c", c_typ, 1)]
|
||||
self.failUnlessEqual(sizeof(X), sizeof(c_typ)*2)
|
||||
|
||||
x = X()
|
||||
self.failUnlessEqual((c_typ, x.a, x.b, x.c), (c_typ, 0, 0, 0))
|
||||
x.a = -1
|
||||
self.failUnlessEqual((c_typ, x.a, x.b, x.c), (c_typ, -1, 0, 0))
|
||||
x.a, x.b = 0, -1
|
||||
self.failUnlessEqual((c_typ, x.a, x.b, x.c), (c_typ, 0, -1, 0))
|
||||
|
||||
|
||||
def test_unsigned(self):
|
||||
for c_typ in unsigned_int_types:
|
||||
class X(Structure):
|
||||
_fields_ = [("a", c_typ, 3),
|
||||
("b", c_typ, 3),
|
||||
("c", c_typ, 1)]
|
||||
self.failUnlessEqual(sizeof(X), sizeof(c_typ))
|
||||
|
||||
x = X()
|
||||
self.failUnlessEqual((c_typ, x.a, x.b, x.c), (c_typ, 0, 0, 0))
|
||||
x.a = -1
|
||||
self.failUnlessEqual((c_typ, x.a, x.b, x.c), (c_typ, 7, 0, 0))
|
||||
x.a, x.b = 0, -1
|
||||
self.failUnlessEqual((c_typ, x.a, x.b, x.c), (c_typ, 0, 7, 0))
|
||||
|
||||
|
||||
def fail_fields(self, *fields):
|
||||
return self.get_except(type(Structure), "X", (),
|
||||
{"_fields_": fields})
|
||||
|
||||
def test_nonint_types(self):
|
||||
# bit fields are not allowed on non-integer types.
|
||||
result = self.fail_fields(("a", c_char_p, 1))
|
||||
self.failUnlessEqual(result, (TypeError, 'bit fields not allowed for type c_char_p'))
|
||||
|
||||
result = self.fail_fields(("a", c_void_p, 1))
|
||||
self.failUnlessEqual(result, (TypeError, 'bit fields not allowed for type c_void_p'))
|
||||
|
||||
if c_int != c_long:
|
||||
result = self.fail_fields(("a", POINTER(c_int), 1))
|
||||
self.failUnlessEqual(result, (TypeError, 'bit fields not allowed for type LP_c_int'))
|
||||
|
||||
result = self.fail_fields(("a", c_char, 1))
|
||||
self.failUnlessEqual(result, (TypeError, 'bit fields not allowed for type c_char'))
|
||||
|
||||
try:
|
||||
c_wchar
|
||||
except NameError:
|
||||
pass
|
||||
else:
|
||||
result = self.fail_fields(("a", c_wchar, 1))
|
||||
self.failUnlessEqual(result, (TypeError, 'bit fields not allowed for type c_wchar'))
|
||||
|
||||
class Dummy(Structure):
|
||||
_fields_ = []
|
||||
|
||||
result = self.fail_fields(("a", Dummy, 1))
|
||||
self.failUnlessEqual(result, (TypeError, 'bit fields not allowed for type Dummy'))
|
||||
|
||||
def test_single_bitfield_size(self):
|
||||
for c_typ in int_types:
|
||||
result = self.fail_fields(("a", c_typ, -1))
|
||||
self.failUnlessEqual(result, (ValueError, 'number of bits invalid for bit field'))
|
||||
|
||||
result = self.fail_fields(("a", c_typ, 0))
|
||||
self.failUnlessEqual(result, (ValueError, 'number of bits invalid for bit field'))
|
||||
|
||||
class X(Structure):
|
||||
_fields_ = [("a", c_typ, 1)]
|
||||
self.failUnlessEqual(sizeof(X), sizeof(c_typ))
|
||||
|
||||
class X(Structure):
|
||||
_fields_ = [("a", c_typ, sizeof(c_typ)*8)]
|
||||
self.failUnlessEqual(sizeof(X), sizeof(c_typ))
|
||||
|
||||
result = self.fail_fields(("a", c_typ, sizeof(c_typ)*8 + 1))
|
||||
self.failUnlessEqual(result, (ValueError, 'number of bits invalid for bit field'))
|
||||
|
||||
def test_multi_bitfields_size(self):
|
||||
class X(Structure):
|
||||
_fields_ = [("a", c_short, 1),
|
||||
("b", c_short, 14),
|
||||
("c", c_short, 1)]
|
||||
self.failUnlessEqual(sizeof(X), sizeof(c_short))
|
||||
|
||||
class X(Structure):
|
||||
_fields_ = [("a", c_short, 1),
|
||||
("a1", c_short),
|
||||
("b", c_short, 14),
|
||||
("c", c_short, 1)]
|
||||
self.failUnlessEqual(sizeof(X), sizeof(c_short)*3)
|
||||
self.failUnlessEqual(X.a.offset, 0)
|
||||
self.failUnlessEqual(X.a1.offset, sizeof(c_short))
|
||||
self.failUnlessEqual(X.b.offset, sizeof(c_short)*2)
|
||||
self.failUnlessEqual(X.c.offset, sizeof(c_short)*2)
|
||||
|
||||
class X(Structure):
|
||||
_fields_ = [("a", c_short, 3),
|
||||
("b", c_short, 14),
|
||||
("c", c_short, 14)]
|
||||
self.failUnlessEqual(sizeof(X), sizeof(c_short)*3)
|
||||
self.failUnlessEqual(X.a.offset, sizeof(c_short)*0)
|
||||
self.failUnlessEqual(X.b.offset, sizeof(c_short)*1)
|
||||
self.failUnlessEqual(X.c.offset, sizeof(c_short)*2)
|
||||
|
||||
|
||||
def get_except(self, func, *args, **kw):
|
||||
try:
|
||||
func(*args, **kw)
|
||||
except Exception, detail:
|
||||
return detail.__class__, str(detail)
|
||||
|
||||
def test_mixed_1(self):
|
||||
class X(Structure):
|
||||
_fields_ = [("a", c_byte, 4),
|
||||
("b", c_int, 4)]
|
||||
if os.name in ("nt", "ce"):
|
||||
self.failUnlessEqual(sizeof(X), sizeof(c_int)*2)
|
||||
else:
|
||||
self.failUnlessEqual(sizeof(X), sizeof(c_int))
|
||||
|
||||
def test_mixed_2(self):
|
||||
class X(Structure):
|
||||
_fields_ = [("a", c_byte, 4),
|
||||
("b", c_int, 32)]
|
||||
self.failUnlessEqual(sizeof(X), sizeof(c_int)*2)
|
||||
|
||||
def test_mixed_3(self):
|
||||
class X(Structure):
|
||||
_fields_ = [("a", c_byte, 4),
|
||||
("b", c_ubyte, 4)]
|
||||
self.failUnlessEqual(sizeof(X), sizeof(c_byte))
|
||||
|
||||
def test_anon_bitfields(self):
|
||||
# anonymous bit-fields gave a strange error message
|
||||
class X(Structure):
|
||||
_fields_ = [("a", c_byte, 4),
|
||||
("b", c_ubyte, 4)]
|
||||
class Y(Structure):
|
||||
_anonymous_ = ["_"]
|
||||
_fields_ = [("_", X)]
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
|
@ -1,54 +0,0 @@
|
|||
from ctypes import *
|
||||
import unittest
|
||||
|
||||
class StringBufferTestCase(unittest.TestCase):
|
||||
|
||||
def test_buffer(self):
|
||||
b = create_string_buffer(32)
|
||||
self.failUnlessEqual(len(b), 32)
|
||||
self.failUnlessEqual(sizeof(b), 32 * sizeof(c_char))
|
||||
self.failUnless(type(b[0]) is str)
|
||||
|
||||
b = create_string_buffer("abc")
|
||||
self.failUnlessEqual(len(b), 4) # trailing nul char
|
||||
self.failUnlessEqual(sizeof(b), 4 * sizeof(c_char))
|
||||
self.failUnless(type(b[0]) is str)
|
||||
self.failUnlessEqual(b[0], "a")
|
||||
self.failUnlessEqual(b[:], "abc\0")
|
||||
|
||||
def test_string_conversion(self):
|
||||
b = create_string_buffer(u"abc")
|
||||
self.failUnlessEqual(len(b), 4) # trailing nul char
|
||||
self.failUnlessEqual(sizeof(b), 4 * sizeof(c_char))
|
||||
self.failUnless(type(b[0]) is str)
|
||||
self.failUnlessEqual(b[0], "a")
|
||||
self.failUnlessEqual(b[:], "abc\0")
|
||||
|
||||
try:
|
||||
c_wchar
|
||||
except NameError:
|
||||
pass
|
||||
else:
|
||||
def test_unicode_buffer(self):
|
||||
b = create_unicode_buffer(32)
|
||||
self.failUnlessEqual(len(b), 32)
|
||||
self.failUnlessEqual(sizeof(b), 32 * sizeof(c_wchar))
|
||||
self.failUnless(type(b[0]) is unicode)
|
||||
|
||||
b = create_unicode_buffer(u"abc")
|
||||
self.failUnlessEqual(len(b), 4) # trailing nul char
|
||||
self.failUnlessEqual(sizeof(b), 4 * sizeof(c_wchar))
|
||||
self.failUnless(type(b[0]) is unicode)
|
||||
self.failUnlessEqual(b[0], u"a")
|
||||
self.failUnlessEqual(b[:], "abc\0")
|
||||
|
||||
def test_unicode_conversion(self):
|
||||
b = create_unicode_buffer("abc")
|
||||
self.failUnlessEqual(len(b), 4) # trailing nul char
|
||||
self.failUnlessEqual(sizeof(b), 4 * sizeof(c_wchar))
|
||||
self.failUnless(type(b[0]) is unicode)
|
||||
self.failUnlessEqual(b[0], u"a")
|
||||
self.failUnlessEqual(b[:], "abc\0")
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
|
@ -1,280 +0,0 @@
|
|||
import sys, unittest, struct, math
|
||||
from binascii import hexlify
|
||||
|
||||
from ctypes import *
|
||||
|
||||
def bin(s):
|
||||
return hexlify(buffer(s)).upper()
|
||||
|
||||
# Each *simple* type that supports different byte orders has an
|
||||
# __ctype_be__ attribute that specifies the same type in BIG ENDIAN
|
||||
# byte order, and a __ctype_le__ attribute that is the same type in
|
||||
# LITTLE ENDIAN byte order.
|
||||
#
|
||||
# For Structures and Unions, these types are created on demand.
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
def X_test(self):
|
||||
print >> sys.stderr, sys.byteorder
|
||||
for i in range(32):
|
||||
bits = BITS()
|
||||
setattr(bits, "i%s" % i, 1)
|
||||
dump(bits)
|
||||
|
||||
def test_endian_short(self):
|
||||
if sys.byteorder == "little":
|
||||
self.failUnless(c_short.__ctype_le__ is c_short)
|
||||
self.failUnless(c_short.__ctype_be__.__ctype_le__ is c_short)
|
||||
else:
|
||||
self.failUnless(c_short.__ctype_be__ is c_short)
|
||||
self.failUnless(c_short.__ctype_le__.__ctype_be__ is c_short)
|
||||
s = c_short.__ctype_be__(0x1234)
|
||||
self.failUnlessEqual(bin(struct.pack(">h", 0x1234)), "1234")
|
||||
self.failUnlessEqual(bin(s), "1234")
|
||||
self.failUnlessEqual(s.value, 0x1234)
|
||||
|
||||
s = c_short.__ctype_le__(0x1234)
|
||||
self.failUnlessEqual(bin(struct.pack("<h", 0x1234)), "3412")
|
||||
self.failUnlessEqual(bin(s), "3412")
|
||||
self.failUnlessEqual(s.value, 0x1234)
|
||||
|
||||
s = c_ushort.__ctype_be__(0x1234)
|
||||
self.failUnlessEqual(bin(struct.pack(">h", 0x1234)), "1234")
|
||||
self.failUnlessEqual(bin(s), "1234")
|
||||
self.failUnlessEqual(s.value, 0x1234)
|
||||
|
||||
s = c_ushort.__ctype_le__(0x1234)
|
||||
self.failUnlessEqual(bin(struct.pack("<h", 0x1234)), "3412")
|
||||
self.failUnlessEqual(bin(s), "3412")
|
||||
self.failUnlessEqual(s.value, 0x1234)
|
||||
|
||||
def test_endian_int(self):
|
||||
if sys.byteorder == "little":
|
||||
self.failUnless(c_int.__ctype_le__ is c_int)
|
||||
self.failUnless(c_int.__ctype_be__.__ctype_le__ is c_int)
|
||||
else:
|
||||
self.failUnless(c_int.__ctype_be__ is c_int)
|
||||
self.failUnless(c_int.__ctype_le__.__ctype_be__ is c_int)
|
||||
|
||||
s = c_int.__ctype_be__(0x12345678)
|
||||
self.failUnlessEqual(bin(struct.pack(">i", 0x12345678)), "12345678")
|
||||
self.failUnlessEqual(bin(s), "12345678")
|
||||
self.failUnlessEqual(s.value, 0x12345678)
|
||||
|
||||
s = c_int.__ctype_le__(0x12345678)
|
||||
self.failUnlessEqual(bin(struct.pack("<i", 0x12345678)), "78563412")
|
||||
self.failUnlessEqual(bin(s), "78563412")
|
||||
self.failUnlessEqual(s.value, 0x12345678)
|
||||
|
||||
s = c_uint.__ctype_be__(0x12345678)
|
||||
self.failUnlessEqual(bin(struct.pack(">I", 0x12345678)), "12345678")
|
||||
self.failUnlessEqual(bin(s), "12345678")
|
||||
self.failUnlessEqual(s.value, 0x12345678)
|
||||
|
||||
s = c_uint.__ctype_le__(0x12345678)
|
||||
self.failUnlessEqual(bin(struct.pack("<I", 0x12345678)), "78563412")
|
||||
self.failUnlessEqual(bin(s), "78563412")
|
||||
self.failUnlessEqual(s.value, 0x12345678)
|
||||
|
||||
def test_endian_longlong(self):
|
||||
if sys.byteorder == "little":
|
||||
self.failUnless(c_longlong.__ctype_le__ is c_longlong)
|
||||
self.failUnless(c_longlong.__ctype_be__.__ctype_le__ is c_longlong)
|
||||
else:
|
||||
self.failUnless(c_longlong.__ctype_be__ is c_longlong)
|
||||
self.failUnless(c_longlong.__ctype_le__.__ctype_be__ is c_longlong)
|
||||
|
||||
s = c_longlong.__ctype_be__(0x1234567890ABCDEF)
|
||||
self.failUnlessEqual(bin(struct.pack(">q", 0x1234567890ABCDEF)), "1234567890ABCDEF")
|
||||
self.failUnlessEqual(bin(s), "1234567890ABCDEF")
|
||||
self.failUnlessEqual(s.value, 0x1234567890ABCDEF)
|
||||
|
||||
s = c_longlong.__ctype_le__(0x1234567890ABCDEF)
|
||||
self.failUnlessEqual(bin(struct.pack("<q", 0x1234567890ABCDEF)), "EFCDAB9078563412")
|
||||
self.failUnlessEqual(bin(s), "EFCDAB9078563412")
|
||||
self.failUnlessEqual(s.value, 0x1234567890ABCDEF)
|
||||
|
||||
s = c_ulonglong.__ctype_be__(0x1234567890ABCDEF)
|
||||
self.failUnlessEqual(bin(struct.pack(">Q", 0x1234567890ABCDEF)), "1234567890ABCDEF")
|
||||
self.failUnlessEqual(bin(s), "1234567890ABCDEF")
|
||||
self.failUnlessEqual(s.value, 0x1234567890ABCDEF)
|
||||
|
||||
s = c_ulonglong.__ctype_le__(0x1234567890ABCDEF)
|
||||
self.failUnlessEqual(bin(struct.pack("<Q", 0x1234567890ABCDEF)), "EFCDAB9078563412")
|
||||
self.failUnlessEqual(bin(s), "EFCDAB9078563412")
|
||||
self.failUnlessEqual(s.value, 0x1234567890ABCDEF)
|
||||
|
||||
def test_endian_float(self):
|
||||
if sys.byteorder == "little":
|
||||
self.failUnless(c_float.__ctype_le__ is c_float)
|
||||
self.failUnless(c_float.__ctype_be__.__ctype_le__ is c_float)
|
||||
else:
|
||||
self.failUnless(c_float.__ctype_be__ is c_float)
|
||||
self.failUnless(c_float.__ctype_le__.__ctype_be__ is c_float)
|
||||
s = c_float(math.pi)
|
||||
self.failUnlessEqual(bin(struct.pack("f", math.pi)), bin(s))
|
||||
# Hm, what's the precision of a float compared to a double?
|
||||
self.failUnlessAlmostEqual(s.value, math.pi, 6)
|
||||
s = c_float.__ctype_le__(math.pi)
|
||||
self.failUnlessAlmostEqual(s.value, math.pi, 6)
|
||||
self.failUnlessEqual(bin(struct.pack("<f", math.pi)), bin(s))
|
||||
s = c_float.__ctype_be__(math.pi)
|
||||
self.failUnlessAlmostEqual(s.value, math.pi, 6)
|
||||
self.failUnlessEqual(bin(struct.pack(">f", math.pi)), bin(s))
|
||||
|
||||
def test_endian_double(self):
|
||||
if sys.byteorder == "little":
|
||||
self.failUnless(c_double.__ctype_le__ is c_double)
|
||||
self.failUnless(c_double.__ctype_be__.__ctype_le__ is c_double)
|
||||
else:
|
||||
self.failUnless(c_double.__ctype_be__ is c_double)
|
||||
self.failUnless(c_double.__ctype_le__.__ctype_be__ is c_double)
|
||||
s = c_double(math.pi)
|
||||
self.failUnlessEqual(s.value, math.pi)
|
||||
self.failUnlessEqual(bin(struct.pack("d", math.pi)), bin(s))
|
||||
s = c_double.__ctype_le__(math.pi)
|
||||
self.failUnlessEqual(s.value, math.pi)
|
||||
self.failUnlessEqual(bin(struct.pack("<d", math.pi)), bin(s))
|
||||
s = c_double.__ctype_be__(math.pi)
|
||||
self.failUnlessEqual(s.value, math.pi)
|
||||
self.failUnlessEqual(bin(struct.pack(">d", math.pi)), bin(s))
|
||||
|
||||
def test_endian_other(self):
|
||||
self.failUnless(c_byte.__ctype_le__ is c_byte)
|
||||
self.failUnless(c_byte.__ctype_be__ is c_byte)
|
||||
|
||||
self.failUnless(c_ubyte.__ctype_le__ is c_ubyte)
|
||||
self.failUnless(c_ubyte.__ctype_be__ is c_ubyte)
|
||||
|
||||
self.failUnless(c_char.__ctype_le__ is c_char)
|
||||
self.failUnless(c_char.__ctype_be__ is c_char)
|
||||
|
||||
def test_struct_fields_1(self):
|
||||
if sys.byteorder == "little":
|
||||
base = BigEndianStructure
|
||||
else:
|
||||
base = LittleEndianStructure
|
||||
|
||||
class T(base):
|
||||
pass
|
||||
_fields_ = [("a", c_ubyte),
|
||||
("b", c_byte),
|
||||
("c", c_short),
|
||||
("d", c_ushort),
|
||||
("e", c_int),
|
||||
("f", c_uint),
|
||||
("g", c_long),
|
||||
("h", c_ulong),
|
||||
("i", c_longlong),
|
||||
("k", c_ulonglong),
|
||||
("l", c_float),
|
||||
("m", c_double),
|
||||
("n", c_char),
|
||||
|
||||
("b1", c_byte, 3),
|
||||
("b2", c_byte, 3),
|
||||
("b3", c_byte, 2),
|
||||
("a", c_int * 3 * 3 * 3)]
|
||||
T._fields_ = _fields_
|
||||
|
||||
# these fields do not support different byte order:
|
||||
for typ in c_wchar, c_void_p, POINTER(c_int):
|
||||
_fields_.append(("x", typ))
|
||||
class T(base):
|
||||
pass
|
||||
self.assertRaises(TypeError, setattr, T, "_fields_", [("x", typ)])
|
||||
|
||||
def test_struct_struct(self):
|
||||
# Nested structures with different byte order not (yet) supported
|
||||
if sys.byteorder == "little":
|
||||
base = BigEndianStructure
|
||||
else:
|
||||
base = LittleEndianStructure
|
||||
|
||||
class T(Structure):
|
||||
_fields_ = [("a", c_int),
|
||||
("b", c_int)]
|
||||
class S(base):
|
||||
pass
|
||||
self.assertRaises(TypeError, setattr, S, "_fields_", [("s", T)])
|
||||
|
||||
def test_struct_fields_2(self):
|
||||
# standard packing in struct uses no alignment.
|
||||
# So, we have to align using pad bytes.
|
||||
#
|
||||
# Unaligned accesses will crash Python (on those platforms that
|
||||
# don't allow it, like sparc solaris).
|
||||
if sys.byteorder == "little":
|
||||
base = BigEndianStructure
|
||||
fmt = ">bxhid"
|
||||
else:
|
||||
base = LittleEndianStructure
|
||||
fmt = "<bxhid"
|
||||
|
||||
class S(base):
|
||||
_fields_ = [("b", c_byte),
|
||||
("h", c_short),
|
||||
("i", c_int),
|
||||
("d", c_double)]
|
||||
|
||||
s1 = S(0x12, 0x1234, 0x12345678, 3.14)
|
||||
s2 = struct.pack(fmt, 0x12, 0x1234, 0x12345678, 3.14)
|
||||
self.failUnlessEqual(bin(s1), bin(s2))
|
||||
|
||||
def test_unaligned_nonnative_struct_fields(self):
|
||||
if sys.byteorder == "little":
|
||||
base = BigEndianStructure
|
||||
fmt = ">b h xi xd"
|
||||
else:
|
||||
base = LittleEndianStructure
|
||||
fmt = "<b h xi xd"
|
||||
|
||||
class S(base):
|
||||
_pack_ = 1
|
||||
_fields_ = [("b", c_byte),
|
||||
|
||||
("h", c_short),
|
||||
|
||||
("_1", c_byte),
|
||||
("i", c_int),
|
||||
|
||||
("_2", c_byte),
|
||||
("d", c_double)]
|
||||
|
||||
s1 = S()
|
||||
s1.b = 0x12
|
||||
s1.h = 0x1234
|
||||
s1.i = 0x12345678
|
||||
s1.d = 3.14
|
||||
s2 = struct.pack(fmt, 0x12, 0x1234, 0x12345678, 3.14)
|
||||
self.failUnlessEqual(bin(s1), bin(s2))
|
||||
|
||||
def test_unaligned_native_struct_fields(self):
|
||||
if sys.byteorder == "little":
|
||||
fmt = "<b h xi xd"
|
||||
else:
|
||||
base = LittleEndianStructure
|
||||
fmt = ">b h xi xd"
|
||||
|
||||
class S(Structure):
|
||||
_pack_ = 1
|
||||
_fields_ = [("b", c_byte),
|
||||
|
||||
("h", c_short),
|
||||
|
||||
("_1", c_byte),
|
||||
("i", c_int),
|
||||
|
||||
("_2", c_byte),
|
||||
("d", c_double)]
|
||||
|
||||
s1 = S()
|
||||
s1.b = 0x12
|
||||
s1.h = 0x1234
|
||||
s1.i = 0x12345678
|
||||
s1.d = 3.14
|
||||
s2 = struct.pack(fmt, 0x12, 0x1234, 0x12345678, 3.14)
|
||||
self.failUnlessEqual(bin(s1), bin(s2))
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
|
@ -1,152 +0,0 @@
|
|||
import unittest
|
||||
from ctypes import *
|
||||
import _ctypes_test
|
||||
|
||||
class Callbacks(unittest.TestCase):
|
||||
functype = CFUNCTYPE
|
||||
|
||||
## def tearDown(self):
|
||||
## import gc
|
||||
## gc.collect()
|
||||
|
||||
def callback(self, *args):
|
||||
self.got_args = args
|
||||
return args[-1]
|
||||
|
||||
def check_type(self, typ, arg):
|
||||
PROTO = self.functype.im_func(typ, typ)
|
||||
result = PROTO(self.callback)(arg)
|
||||
if typ == c_float:
|
||||
self.failUnlessAlmostEqual(result, arg, places=5)
|
||||
else:
|
||||
self.failUnlessEqual(self.got_args, (arg,))
|
||||
self.failUnlessEqual(result, arg)
|
||||
|
||||
PROTO = self.functype.im_func(typ, c_byte, typ)
|
||||
result = PROTO(self.callback)(-3, arg)
|
||||
if typ == c_float:
|
||||
self.failUnlessAlmostEqual(result, arg, places=5)
|
||||
else:
|
||||
self.failUnlessEqual(self.got_args, (-3, arg))
|
||||
self.failUnlessEqual(result, arg)
|
||||
|
||||
################
|
||||
|
||||
def test_byte(self):
|
||||
self.check_type(c_byte, 42)
|
||||
self.check_type(c_byte, -42)
|
||||
|
||||
def test_ubyte(self):
|
||||
self.check_type(c_ubyte, 42)
|
||||
|
||||
def test_short(self):
|
||||
self.check_type(c_short, 42)
|
||||
self.check_type(c_short, -42)
|
||||
|
||||
def test_ushort(self):
|
||||
self.check_type(c_ushort, 42)
|
||||
|
||||
def test_int(self):
|
||||
self.check_type(c_int, 42)
|
||||
self.check_type(c_int, -42)
|
||||
|
||||
def test_uint(self):
|
||||
self.check_type(c_uint, 42)
|
||||
|
||||
def test_long(self):
|
||||
self.check_type(c_long, 42)
|
||||
self.check_type(c_long, -42)
|
||||
|
||||
def test_ulong(self):
|
||||
self.check_type(c_ulong, 42)
|
||||
|
||||
def test_longlong(self):
|
||||
self.check_type(c_longlong, 42)
|
||||
self.check_type(c_longlong, -42)
|
||||
|
||||
def test_ulonglong(self):
|
||||
self.check_type(c_ulonglong, 42)
|
||||
|
||||
def test_float(self):
|
||||
# only almost equal: double -> float -> double
|
||||
import math
|
||||
self.check_type(c_float, math.e)
|
||||
self.check_type(c_float, -math.e)
|
||||
|
||||
def test_double(self):
|
||||
self.check_type(c_double, 3.14)
|
||||
self.check_type(c_double, -3.14)
|
||||
|
||||
def test_char(self):
|
||||
self.check_type(c_char, "x")
|
||||
self.check_type(c_char, "a")
|
||||
|
||||
# disabled: would now (correctly) raise a RuntimeWarning about
|
||||
# a memory leak. A callback function cannot return a non-integral
|
||||
# C type without causing a memory leak.
|
||||
## def test_char_p(self):
|
||||
## self.check_type(c_char_p, "abc")
|
||||
## self.check_type(c_char_p, "def")
|
||||
|
||||
def test_pyobject(self):
|
||||
o = ()
|
||||
from sys import getrefcount as grc
|
||||
for o in (), [], object():
|
||||
initial = grc(o)
|
||||
# This call leaks a reference to 'o'...
|
||||
self.check_type(py_object, o)
|
||||
before = grc(o)
|
||||
# ...but this call doesn't leak any more. Where is the refcount?
|
||||
self.check_type(py_object, o)
|
||||
after = grc(o)
|
||||
self.failUnlessEqual((after, o), (before, o))
|
||||
|
||||
def test_unsupported_restype_1(self):
|
||||
# Only "fundamental" result types are supported for callback
|
||||
# functions, the type must have a non-NULL stgdict->setfunc.
|
||||
# POINTER(c_double), for example, is not supported.
|
||||
|
||||
prototype = self.functype.im_func(POINTER(c_double))
|
||||
# The type is checked when the prototype is called
|
||||
self.assertRaises(TypeError, prototype, lambda: None)
|
||||
|
||||
def test_unsupported_restype_2(self):
|
||||
prototype = self.functype.im_func(object)
|
||||
self.assertRaises(TypeError, prototype, lambda: None)
|
||||
|
||||
try:
|
||||
WINFUNCTYPE
|
||||
except NameError:
|
||||
pass
|
||||
else:
|
||||
class StdcallCallbacks(Callbacks):
|
||||
functype = WINFUNCTYPE
|
||||
|
||||
################################################################
|
||||
|
||||
class SampleCallbacksTestCase(unittest.TestCase):
|
||||
|
||||
def test_integrate(self):
|
||||
# Derived from some then non-working code, posted by David Foster
|
||||
dll = CDLL(_ctypes_test.__file__)
|
||||
|
||||
# The function prototype called by 'integrate': double func(double);
|
||||
CALLBACK = CFUNCTYPE(c_double, c_double)
|
||||
|
||||
# The integrate function itself, exposed from the _ctypes_test dll
|
||||
integrate = dll.integrate
|
||||
integrate.argtypes = (c_double, c_double, CALLBACK, c_long)
|
||||
integrate.restype = c_double
|
||||
|
||||
def func(x):
|
||||
return x**2
|
||||
|
||||
result = integrate(0.0, 1.0, CALLBACK(func), 10)
|
||||
diff = abs(result - 1./3.)
|
||||
|
||||
self.failUnless(diff < 0.01, "%s not less than 0.01" % diff)
|
||||
|
||||
################################################################
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -1,77 +0,0 @@
|
|||
from ctypes import *
|
||||
import unittest
|
||||
import sys
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
|
||||
def test_array2pointer(self):
|
||||
array = (c_int * 3)(42, 17, 2)
|
||||
|
||||
# casting an array to a pointer works.
|
||||
ptr = cast(array, POINTER(c_int))
|
||||
self.failUnlessEqual([ptr[i] for i in range(3)], [42, 17, 2])
|
||||
|
||||
if 2*sizeof(c_short) == sizeof(c_int):
|
||||
ptr = cast(array, POINTER(c_short))
|
||||
if sys.byteorder == "little":
|
||||
self.failUnlessEqual([ptr[i] for i in range(6)],
|
||||
[42, 0, 17, 0, 2, 0])
|
||||
else:
|
||||
self.failUnlessEqual([ptr[i] for i in range(6)],
|
||||
[0, 42, 0, 17, 0, 2])
|
||||
|
||||
def test_address2pointer(self):
|
||||
array = (c_int * 3)(42, 17, 2)
|
||||
|
||||
address = addressof(array)
|
||||
ptr = cast(c_void_p(address), POINTER(c_int))
|
||||
self.failUnlessEqual([ptr[i] for i in range(3)], [42, 17, 2])
|
||||
|
||||
ptr = cast(address, POINTER(c_int))
|
||||
self.failUnlessEqual([ptr[i] for i in range(3)], [42, 17, 2])
|
||||
|
||||
def test_p2a_objects(self):
|
||||
array = (c_char_p * 5)()
|
||||
self.failUnlessEqual(array._objects, None)
|
||||
array[0] = "foo bar"
|
||||
self.failUnlessEqual(array._objects, {'0': "foo bar"})
|
||||
|
||||
p = cast(array, POINTER(c_char_p))
|
||||
# array and p share a common _objects attribute
|
||||
self.failUnless(p._objects is array._objects)
|
||||
self.failUnlessEqual(array._objects, {'0': "foo bar", id(array): array})
|
||||
p[0] = "spam spam"
|
||||
self.failUnlessEqual(p._objects, {'0': "spam spam", id(array): array})
|
||||
self.failUnless(array._objects is p._objects)
|
||||
p[1] = "foo bar"
|
||||
self.failUnlessEqual(p._objects, {'1': 'foo bar', '0': "spam spam", id(array): array})
|
||||
self.failUnless(array._objects is p._objects)
|
||||
|
||||
def test_other(self):
|
||||
p = cast((c_int * 4)(1, 2, 3, 4), POINTER(c_int))
|
||||
self.failUnlessEqual(p[:4], [1,2, 3, 4])
|
||||
c_int()
|
||||
self.failUnlessEqual(p[:4], [1, 2, 3, 4])
|
||||
p[2] = 96
|
||||
self.failUnlessEqual(p[:4], [1, 2, 96, 4])
|
||||
c_int()
|
||||
self.failUnlessEqual(p[:4], [1, 2, 96, 4])
|
||||
|
||||
def test_char_p(self):
|
||||
# This didn't work: bad argument to internal function
|
||||
s = c_char_p("hiho")
|
||||
self.failUnlessEqual(cast(cast(s, c_void_p), c_char_p).value,
|
||||
"hiho")
|
||||
|
||||
try:
|
||||
c_wchar_p
|
||||
except NameError:
|
||||
pass
|
||||
else:
|
||||
def test_wchar_p(self):
|
||||
s = c_wchar_p("hiho")
|
||||
self.failUnlessEqual(cast(cast(s, c_void_p), c_wchar_p).value,
|
||||
"hiho")
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
|
@ -1,199 +0,0 @@
|
|||
# A lot of failures in these tests on Mac OS X.
|
||||
# Byte order related?
|
||||
|
||||
import unittest
|
||||
from ctypes import *
|
||||
|
||||
import _ctypes_test
|
||||
|
||||
class CFunctions(unittest.TestCase):
|
||||
_dll = CDLL(_ctypes_test.__file__)
|
||||
|
||||
def S(self):
|
||||
return c_longlong.in_dll(self._dll, "last_tf_arg_s").value
|
||||
def U(self):
|
||||
return c_ulonglong.in_dll(self._dll, "last_tf_arg_u").value
|
||||
|
||||
def test_byte(self):
|
||||
self._dll.tf_b.restype = c_byte
|
||||
self._dll.tf_b.argtypes = (c_byte,)
|
||||
self.failUnlessEqual(self._dll.tf_b(-126), -42)
|
||||
self.failUnlessEqual(self.S(), -126)
|
||||
|
||||
def test_byte_plus(self):
|
||||
self._dll.tf_bb.restype = c_byte
|
||||
self._dll.tf_bb.argtypes = (c_byte, c_byte)
|
||||
self.failUnlessEqual(self._dll.tf_bb(0, -126), -42)
|
||||
self.failUnlessEqual(self.S(), -126)
|
||||
|
||||
def test_ubyte(self):
|
||||
self._dll.tf_B.restype = c_ubyte
|
||||
self._dll.tf_B.argtypes = (c_ubyte,)
|
||||
self.failUnlessEqual(self._dll.tf_B(255), 85)
|
||||
self.failUnlessEqual(self.U(), 255)
|
||||
|
||||
def test_ubyte_plus(self):
|
||||
self._dll.tf_bB.restype = c_ubyte
|
||||
self._dll.tf_bB.argtypes = (c_byte, c_ubyte)
|
||||
self.failUnlessEqual(self._dll.tf_bB(0, 255), 85)
|
||||
self.failUnlessEqual(self.U(), 255)
|
||||
|
||||
def test_short(self):
|
||||
self._dll.tf_h.restype = c_short
|
||||
self._dll.tf_h.argtypes = (c_short,)
|
||||
self.failUnlessEqual(self._dll.tf_h(-32766), -10922)
|
||||
self.failUnlessEqual(self.S(), -32766)
|
||||
|
||||
def test_short_plus(self):
|
||||
self._dll.tf_bh.restype = c_short
|
||||
self._dll.tf_bh.argtypes = (c_byte, c_short)
|
||||
self.failUnlessEqual(self._dll.tf_bh(0, -32766), -10922)
|
||||
self.failUnlessEqual(self.S(), -32766)
|
||||
|
||||
def test_ushort(self):
|
||||
self._dll.tf_H.restype = c_ushort
|
||||
self._dll.tf_H.argtypes = (c_ushort,)
|
||||
self.failUnlessEqual(self._dll.tf_H(65535), 21845)
|
||||
self.failUnlessEqual(self.U(), 65535)
|
||||
|
||||
def test_ushort_plus(self):
|
||||
self._dll.tf_bH.restype = c_ushort
|
||||
self._dll.tf_bH.argtypes = (c_byte, c_ushort)
|
||||
self.failUnlessEqual(self._dll.tf_bH(0, 65535), 21845)
|
||||
self.failUnlessEqual(self.U(), 65535)
|
||||
|
||||
def test_int(self):
|
||||
self._dll.tf_i.restype = c_int
|
||||
self._dll.tf_i.argtypes = (c_int,)
|
||||
self.failUnlessEqual(self._dll.tf_i(-2147483646), -715827882)
|
||||
self.failUnlessEqual(self.S(), -2147483646)
|
||||
|
||||
def test_int_plus(self):
|
||||
self._dll.tf_bi.restype = c_int
|
||||
self._dll.tf_bi.argtypes = (c_byte, c_int)
|
||||
self.failUnlessEqual(self._dll.tf_bi(0, -2147483646), -715827882)
|
||||
self.failUnlessEqual(self.S(), -2147483646)
|
||||
|
||||
def test_uint(self):
|
||||
self._dll.tf_I.restype = c_uint
|
||||
self._dll.tf_I.argtypes = (c_uint,)
|
||||
self.failUnlessEqual(self._dll.tf_I(4294967295), 1431655765)
|
||||
self.failUnlessEqual(self.U(), 4294967295)
|
||||
|
||||
def test_uint_plus(self):
|
||||
self._dll.tf_bI.restype = c_uint
|
||||
self._dll.tf_bI.argtypes = (c_byte, c_uint)
|
||||
self.failUnlessEqual(self._dll.tf_bI(0, 4294967295), 1431655765)
|
||||
self.failUnlessEqual(self.U(), 4294967295)
|
||||
|
||||
def test_long(self):
|
||||
self._dll.tf_l.restype = c_long
|
||||
self._dll.tf_l.argtypes = (c_long,)
|
||||
self.failUnlessEqual(self._dll.tf_l(-2147483646), -715827882)
|
||||
self.failUnlessEqual(self.S(), -2147483646)
|
||||
|
||||
def test_long_plus(self):
|
||||
self._dll.tf_bl.restype = c_long
|
||||
self._dll.tf_bl.argtypes = (c_byte, c_long)
|
||||
self.failUnlessEqual(self._dll.tf_bl(0, -2147483646), -715827882)
|
||||
self.failUnlessEqual(self.S(), -2147483646)
|
||||
|
||||
def test_ulong(self):
|
||||
self._dll.tf_L.restype = c_ulong
|
||||
self._dll.tf_L.argtypes = (c_ulong,)
|
||||
self.failUnlessEqual(self._dll.tf_L(4294967295), 1431655765)
|
||||
self.failUnlessEqual(self.U(), 4294967295)
|
||||
|
||||
def test_ulong_plus(self):
|
||||
self._dll.tf_bL.restype = c_ulong
|
||||
self._dll.tf_bL.argtypes = (c_char, c_ulong)
|
||||
self.failUnlessEqual(self._dll.tf_bL(' ', 4294967295), 1431655765)
|
||||
self.failUnlessEqual(self.U(), 4294967295)
|
||||
|
||||
def test_longlong(self):
|
||||
self._dll.tf_q.restype = c_longlong
|
||||
self._dll.tf_q.argtypes = (c_longlong, )
|
||||
self.failUnlessEqual(self._dll.tf_q(-9223372036854775806), -3074457345618258602)
|
||||
self.failUnlessEqual(self.S(), -9223372036854775806)
|
||||
|
||||
def test_longlong_plus(self):
|
||||
self._dll.tf_bq.restype = c_longlong
|
||||
self._dll.tf_bq.argtypes = (c_byte, c_longlong)
|
||||
self.failUnlessEqual(self._dll.tf_bq(0, -9223372036854775806), -3074457345618258602)
|
||||
self.failUnlessEqual(self.S(), -9223372036854775806)
|
||||
|
||||
def test_ulonglong(self):
|
||||
self._dll.tf_Q.restype = c_ulonglong
|
||||
self._dll.tf_Q.argtypes = (c_ulonglong, )
|
||||
self.failUnlessEqual(self._dll.tf_Q(18446744073709551615), 6148914691236517205)
|
||||
self.failUnlessEqual(self.U(), 18446744073709551615)
|
||||
|
||||
def test_ulonglong_plus(self):
|
||||
self._dll.tf_bQ.restype = c_ulonglong
|
||||
self._dll.tf_bQ.argtypes = (c_byte, c_ulonglong)
|
||||
self.failUnlessEqual(self._dll.tf_bQ(0, 18446744073709551615), 6148914691236517205)
|
||||
self.failUnlessEqual(self.U(), 18446744073709551615)
|
||||
|
||||
def test_float(self):
|
||||
self._dll.tf_f.restype = c_float
|
||||
self._dll.tf_f.argtypes = (c_float,)
|
||||
self.failUnlessEqual(self._dll.tf_f(-42.), -14.)
|
||||
self.failUnlessEqual(self.S(), -42)
|
||||
|
||||
def test_float_plus(self):
|
||||
self._dll.tf_bf.restype = c_float
|
||||
self._dll.tf_bf.argtypes = (c_byte, c_float)
|
||||
self.failUnlessEqual(self._dll.tf_bf(0, -42.), -14.)
|
||||
self.failUnlessEqual(self.S(), -42)
|
||||
|
||||
def test_double(self):
|
||||
self._dll.tf_d.restype = c_double
|
||||
self._dll.tf_d.argtypes = (c_double,)
|
||||
self.failUnlessEqual(self._dll.tf_d(42.), 14.)
|
||||
self.failUnlessEqual(self.S(), 42)
|
||||
|
||||
def test_double_plus(self):
|
||||
self._dll.tf_bd.restype = c_double
|
||||
self._dll.tf_bd.argtypes = (c_byte, c_double)
|
||||
self.failUnlessEqual(self._dll.tf_bd(0, 42.), 14.)
|
||||
self.failUnlessEqual(self.S(), 42)
|
||||
|
||||
def test_callwithresult(self):
|
||||
def process_result(result):
|
||||
return result * 2
|
||||
self._dll.tf_i.restype = process_result
|
||||
self._dll.tf_i.argtypes = (c_int,)
|
||||
self.failUnlessEqual(self._dll.tf_i(42), 28)
|
||||
self.failUnlessEqual(self.S(), 42)
|
||||
self.failUnlessEqual(self._dll.tf_i(-42), -28)
|
||||
self.failUnlessEqual(self.S(), -42)
|
||||
|
||||
def test_void(self):
|
||||
self._dll.tv_i.restype = None
|
||||
self._dll.tv_i.argtypes = (c_int,)
|
||||
self.failUnlessEqual(self._dll.tv_i(42), None)
|
||||
self.failUnlessEqual(self.S(), 42)
|
||||
self.failUnlessEqual(self._dll.tv_i(-42), None)
|
||||
self.failUnlessEqual(self.S(), -42)
|
||||
|
||||
# The following repeates the above tests with stdcall functions (where
|
||||
# they are available)
|
||||
try:
|
||||
WinDLL
|
||||
except NameError:
|
||||
pass
|
||||
else:
|
||||
class stdcall_dll(WinDLL):
|
||||
def __getattr__(self, name):
|
||||
if name[:2] == '__' and name[-2:] == '__':
|
||||
raise AttributeError, name
|
||||
func = self._FuncPtr(("s_" + name, self))
|
||||
setattr(self, name, func)
|
||||
return func
|
||||
|
||||
class stdcallCFunctions(CFunctions):
|
||||
_dll = stdcall_dll(_ctypes_test.__file__)
|
||||
pass
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -1,40 +0,0 @@
|
|||
import unittest
|
||||
import sys
|
||||
|
||||
from ctypes import *
|
||||
|
||||
class CHECKED(c_int):
|
||||
def _check_retval_(value):
|
||||
# Receives a CHECKED instance.
|
||||
return str(value.value)
|
||||
_check_retval_ = staticmethod(_check_retval_)
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
|
||||
def test_checkretval(self):
|
||||
|
||||
import _ctypes_test
|
||||
dll = CDLL(_ctypes_test.__file__)
|
||||
self.failUnlessEqual(42, dll._testfunc_p_p(42))
|
||||
|
||||
dll._testfunc_p_p.restype = CHECKED
|
||||
self.failUnlessEqual("42", dll._testfunc_p_p(42))
|
||||
|
||||
dll._testfunc_p_p.restype = None
|
||||
self.failUnlessEqual(None, dll._testfunc_p_p(42))
|
||||
|
||||
del dll._testfunc_p_p.restype
|
||||
self.failUnlessEqual(42, dll._testfunc_p_p(42))
|
||||
|
||||
try:
|
||||
oledll
|
||||
except NameError:
|
||||
pass
|
||||
else:
|
||||
def test_oledll(self):
|
||||
self.failUnlessRaises(WindowsError,
|
||||
oledll.oleaut32.CreateTypeLib2,
|
||||
0, 0, 0)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
|
@ -1,19 +0,0 @@
|
|||
import sys
|
||||
from ctypes import *
|
||||
|
||||
##class HMODULE(Structure):
|
||||
## _fields_ = [("value", c_void_p)]
|
||||
|
||||
## def __repr__(self):
|
||||
## return "<HMODULE %s>" % self.value
|
||||
|
||||
##windll.kernel32.GetModuleHandleA.restype = HMODULE
|
||||
|
||||
##print windll.kernel32.GetModuleHandleA("python23.dll")
|
||||
##print hex(sys.dllhandle)
|
||||
|
||||
##def nonzero(handle):
|
||||
## return (GetLastError(), handle)
|
||||
|
||||
##windll.kernel32.GetModuleHandleA.errcheck = nonzero
|
||||
##print windll.kernel32.GetModuleHandleA("spam")
|
|
@ -1,104 +0,0 @@
|
|||
import unittest
|
||||
import os, sys
|
||||
from ctypes import *
|
||||
from ctypes.util import find_library
|
||||
from ctypes.test import is_resource_enabled
|
||||
|
||||
if sys.platform == "win32":
|
||||
lib_gl = find_library("OpenGL32")
|
||||
lib_glu = find_library("Glu32")
|
||||
lib_glut = find_library("glut32")
|
||||
lib_gle = None
|
||||
elif sys.platform == "darwin":
|
||||
lib_gl = lib_glu = find_library("OpenGL")
|
||||
lib_glut = find_library("GLUT")
|
||||
lib_gle = None
|
||||
else:
|
||||
lib_gl = find_library("GL")
|
||||
lib_glu = find_library("GLU")
|
||||
lib_glut = find_library("glut")
|
||||
lib_gle = find_library("gle")
|
||||
|
||||
## print, for debugging
|
||||
if is_resource_enabled("printing"):
|
||||
if lib_gl or lib_glu or lib_glut or lib_gle:
|
||||
print "OpenGL libraries:"
|
||||
for item in (("GL", lib_gl),
|
||||
("GLU", lib_glu),
|
||||
("glut", lib_glut),
|
||||
("gle", lib_gle)):
|
||||
print "\t", item
|
||||
|
||||
|
||||
# On some systems, loading the OpenGL libraries needs the RTLD_GLOBAL mode.
|
||||
class Test_OpenGL_libs(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.gl = self.glu = self.gle = self.glut = None
|
||||
if lib_gl:
|
||||
self.gl = CDLL(lib_gl, mode=RTLD_GLOBAL)
|
||||
if lib_glu:
|
||||
self.glu = CDLL(lib_glu, RTLD_GLOBAL)
|
||||
if lib_glut:
|
||||
# On some systems, additional libraries seem to be
|
||||
# required, loading glut fails with
|
||||
# "OSError: /usr/lib/libglut.so.3: undefined symbol: XGetExtensionVersion"
|
||||
# I cannot figure out how to repair the test on these
|
||||
# systems (red hat), so we ignore it when the glut or gle
|
||||
# libraries cannot be loaded. See also:
|
||||
# https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1478253&group_id=5470
|
||||
# http://mail.python.org/pipermail/python-dev/2006-May/064789.html
|
||||
try:
|
||||
self.glut = CDLL(lib_glut)
|
||||
except OSError:
|
||||
pass
|
||||
if lib_gle:
|
||||
try:
|
||||
self.gle = CDLL(lib_gle)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
if lib_gl:
|
||||
def test_gl(self):
|
||||
if self.gl:
|
||||
self.gl.glClearIndex
|
||||
|
||||
if lib_glu:
|
||||
def test_glu(self):
|
||||
if self.glu:
|
||||
self.glu.gluBeginCurve
|
||||
|
||||
if lib_glut:
|
||||
def test_glut(self):
|
||||
if self.glut:
|
||||
self.glut.glutWireTetrahedron
|
||||
|
||||
if lib_gle:
|
||||
def test_gle(self):
|
||||
if self.gle:
|
||||
self.gle.gleGetJoinStyle
|
||||
|
||||
##if os.name == "posix" and sys.platform != "darwin":
|
||||
|
||||
## # On platforms where the default shared library suffix is '.so',
|
||||
## # at least some libraries can be loaded as attributes of the cdll
|
||||
## # object, since ctypes now tries loading the lib again
|
||||
## # with '.so' appended of the first try fails.
|
||||
## #
|
||||
## # Won't work for libc, unfortunately. OTOH, it isn't
|
||||
## # needed for libc since this is already mapped into the current
|
||||
## # process (?)
|
||||
## #
|
||||
## # On MAC OSX, it won't work either, because dlopen() needs a full path,
|
||||
## # and the default suffix is either none or '.dylib'.
|
||||
|
||||
## class LoadLibs(unittest.TestCase):
|
||||
## def test_libm(self):
|
||||
## import math
|
||||
## libm = cdll.libm
|
||||
## sqrt = libm.sqrt
|
||||
## sqrt.argtypes = (c_double,)
|
||||
## sqrt.restype = c_double
|
||||
## self.failUnlessEqual(sqrt(2), math.sqrt(2))
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
|
@ -1,127 +0,0 @@
|
|||
import os, unittest
|
||||
from ctypes import *
|
||||
|
||||
try:
|
||||
WINFUNCTYPE
|
||||
except NameError:
|
||||
# fake to enable this test on Linux
|
||||
WINFUNCTYPE = CFUNCTYPE
|
||||
|
||||
import _ctypes_test
|
||||
lib = CDLL(_ctypes_test.__file__)
|
||||
|
||||
class CFuncPtrTestCase(unittest.TestCase):
|
||||
def test_basic(self):
|
||||
X = WINFUNCTYPE(c_int, c_int, c_int)
|
||||
|
||||
def func(*args):
|
||||
return len(args)
|
||||
|
||||
x = X(func)
|
||||
self.failUnlessEqual(x.restype, c_int)
|
||||
self.failUnlessEqual(x.argtypes, (c_int, c_int))
|
||||
self.failUnlessEqual(sizeof(x), sizeof(c_voidp))
|
||||
self.failUnlessEqual(sizeof(X), sizeof(c_voidp))
|
||||
|
||||
def test_first(self):
|
||||
StdCallback = WINFUNCTYPE(c_int, c_int, c_int)
|
||||
CdeclCallback = CFUNCTYPE(c_int, c_int, c_int)
|
||||
|
||||
def func(a, b):
|
||||
return a + b
|
||||
|
||||
s = StdCallback(func)
|
||||
c = CdeclCallback(func)
|
||||
|
||||
self.failUnlessEqual(s(1, 2), 3)
|
||||
self.failUnlessEqual(c(1, 2), 3)
|
||||
# The following no longer raises a TypeError - it is now
|
||||
# possible, as in C, to call cdecl functions with more parameters.
|
||||
#self.assertRaises(TypeError, c, 1, 2, 3)
|
||||
self.failUnlessEqual(c(1, 2, 3, 4, 5, 6), 3)
|
||||
if not WINFUNCTYPE is CFUNCTYPE and os.name != "ce":
|
||||
self.assertRaises(TypeError, s, 1, 2, 3)
|
||||
|
||||
def test_structures(self):
|
||||
WNDPROC = WINFUNCTYPE(c_long, c_int, c_int, c_int, c_int)
|
||||
|
||||
def wndproc(hwnd, msg, wParam, lParam):
|
||||
return hwnd + msg + wParam + lParam
|
||||
|
||||
HINSTANCE = c_int
|
||||
HICON = c_int
|
||||
HCURSOR = c_int
|
||||
LPCTSTR = c_char_p
|
||||
|
||||
class WNDCLASS(Structure):
|
||||
_fields_ = [("style", c_uint),
|
||||
("lpfnWndProc", WNDPROC),
|
||||
("cbClsExtra", c_int),
|
||||
("cbWndExtra", c_int),
|
||||
("hInstance", HINSTANCE),
|
||||
("hIcon", HICON),
|
||||
("hCursor", HCURSOR),
|
||||
("lpszMenuName", LPCTSTR),
|
||||
("lpszClassName", LPCTSTR)]
|
||||
|
||||
wndclass = WNDCLASS()
|
||||
wndclass.lpfnWndProc = WNDPROC(wndproc)
|
||||
|
||||
WNDPROC_2 = WINFUNCTYPE(c_long, c_int, c_int, c_int, c_int)
|
||||
|
||||
# This is no longer true, now that WINFUNCTYPE caches created types internally.
|
||||
## # CFuncPtr subclasses are compared by identity, so this raises a TypeError:
|
||||
## self.assertRaises(TypeError, setattr, wndclass,
|
||||
## "lpfnWndProc", WNDPROC_2(wndproc))
|
||||
# instead:
|
||||
|
||||
self.failUnless(WNDPROC is WNDPROC_2)
|
||||
# 'wndclass.lpfnWndProc' leaks 94 references. Why?
|
||||
self.failUnlessEqual(wndclass.lpfnWndProc(1, 2, 3, 4), 10)
|
||||
|
||||
|
||||
f = wndclass.lpfnWndProc
|
||||
|
||||
del wndclass
|
||||
del wndproc
|
||||
|
||||
self.failUnlessEqual(f(10, 11, 12, 13), 46)
|
||||
|
||||
def test_dllfunctions(self):
|
||||
|
||||
def NoNullHandle(value):
|
||||
if not value:
|
||||
raise WinError()
|
||||
return value
|
||||
|
||||
strchr = lib.my_strchr
|
||||
strchr.restype = c_char_p
|
||||
strchr.argtypes = (c_char_p, c_char)
|
||||
self.failUnlessEqual(strchr("abcdefghi", "b"), "bcdefghi")
|
||||
self.failUnlessEqual(strchr("abcdefghi", "x"), None)
|
||||
|
||||
|
||||
strtok = lib.my_strtok
|
||||
strtok.restype = c_char_p
|
||||
# Neither of this does work: strtok changes the buffer it is passed
|
||||
## strtok.argtypes = (c_char_p, c_char_p)
|
||||
## strtok.argtypes = (c_string, c_char_p)
|
||||
|
||||
def c_string(init):
|
||||
size = len(init) + 1
|
||||
return (c_char*size)(*init)
|
||||
|
||||
s = "a\nb\nc"
|
||||
b = c_string(s)
|
||||
|
||||
## b = (c_char * (len(s)+1))()
|
||||
## b.value = s
|
||||
|
||||
## b = c_string(s)
|
||||
self.failUnlessEqual(strtok(b, "\n"), "a")
|
||||
self.failUnlessEqual(strtok(None, "\n"), "b")
|
||||
self.failUnlessEqual(strtok(None, "\n"), "c")
|
||||
self.failUnlessEqual(strtok(None, "\n"), None)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -1,395 +0,0 @@
|
|||
"""
|
||||
Here is probably the place to write the docs, since the test-cases
|
||||
show how the type behave.
|
||||
|
||||
Later...
|
||||
"""
|
||||
|
||||
from ctypes import *
|
||||
import sys, unittest
|
||||
|
||||
try:
|
||||
WINFUNCTYPE
|
||||
except NameError:
|
||||
# fake to enable this test on Linux
|
||||
WINFUNCTYPE = CFUNCTYPE
|
||||
|
||||
import _ctypes_test
|
||||
dll = CDLL(_ctypes_test.__file__)
|
||||
if sys.platform == "win32":
|
||||
windll = WinDLL(_ctypes_test.__file__)
|
||||
|
||||
class POINT(Structure):
|
||||
_fields_ = [("x", c_int), ("y", c_int)]
|
||||
class RECT(Structure):
|
||||
_fields_ = [("left", c_int), ("top", c_int),
|
||||
("right", c_int), ("bottom", c_int)]
|
||||
class FunctionTestCase(unittest.TestCase):
|
||||
|
||||
def test_mro(self):
|
||||
# in Python 2.3, this raises TypeError: MRO conflict among bases classes,
|
||||
# in Python 2.2 it works.
|
||||
#
|
||||
# But in early versions of _ctypes.c, the result of tp_new
|
||||
# wasn't checked, and it even crashed Python.
|
||||
# Found by Greg Chapman.
|
||||
|
||||
try:
|
||||
class X(object, Array):
|
||||
_length_ = 5
|
||||
_type_ = "i"
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
|
||||
from _ctypes import _Pointer
|
||||
try:
|
||||
class X(object, _Pointer):
|
||||
pass
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
from _ctypes import _SimpleCData
|
||||
try:
|
||||
class X(object, _SimpleCData):
|
||||
_type_ = "i"
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
try:
|
||||
class X(object, Structure):
|
||||
_fields_ = []
|
||||
except TypeError:
|
||||
pass
|
||||
|
||||
|
||||
def test_wchar_parm(self):
|
||||
try:
|
||||
c_wchar
|
||||
except NameError:
|
||||
return
|
||||
f = dll._testfunc_i_bhilfd
|
||||
f.argtypes = [c_byte, c_wchar, c_int, c_long, c_float, c_double]
|
||||
result = f(1, u"x", 3, 4, 5.0, 6.0)
|
||||
self.failUnlessEqual(result, 139)
|
||||
self.failUnlessEqual(type(result), int)
|
||||
|
||||
def test_wchar_result(self):
|
||||
try:
|
||||
c_wchar
|
||||
except NameError:
|
||||
return
|
||||
f = dll._testfunc_i_bhilfd
|
||||
f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_double]
|
||||
f.restype = c_wchar
|
||||
result = f(0, 0, 0, 0, 0, 0)
|
||||
self.failUnlessEqual(result, u'\x00')
|
||||
|
||||
def test_voidresult(self):
|
||||
f = dll._testfunc_v
|
||||
f.restype = None
|
||||
f.argtypes = [c_int, c_int, POINTER(c_int)]
|
||||
result = c_int()
|
||||
self.failUnlessEqual(None, f(1, 2, byref(result)))
|
||||
self.failUnlessEqual(result.value, 3)
|
||||
|
||||
def test_intresult(self):
|
||||
f = dll._testfunc_i_bhilfd
|
||||
f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_double]
|
||||
f.restype = c_int
|
||||
result = f(1, 2, 3, 4, 5.0, 6.0)
|
||||
self.failUnlessEqual(result, 21)
|
||||
self.failUnlessEqual(type(result), int)
|
||||
|
||||
result = f(-1, -2, -3, -4, -5.0, -6.0)
|
||||
self.failUnlessEqual(result, -21)
|
||||
self.failUnlessEqual(type(result), int)
|
||||
|
||||
# If we declare the function to return a short,
|
||||
# is the high part split off?
|
||||
f.restype = c_short
|
||||
result = f(1, 2, 3, 4, 5.0, 6.0)
|
||||
self.failUnlessEqual(result, 21)
|
||||
self.failUnlessEqual(type(result), int)
|
||||
|
||||
result = f(1, 2, 3, 0x10004, 5.0, 6.0)
|
||||
self.failUnlessEqual(result, 21)
|
||||
self.failUnlessEqual(type(result), int)
|
||||
|
||||
# You cannot assing character format codes as restype any longer
|
||||
self.assertRaises(TypeError, setattr, f, "restype", "i")
|
||||
|
||||
def test_floatresult(self):
|
||||
f = dll._testfunc_f_bhilfd
|
||||
f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_double]
|
||||
f.restype = c_float
|
||||
result = f(1, 2, 3, 4, 5.0, 6.0)
|
||||
self.failUnlessEqual(result, 21)
|
||||
self.failUnlessEqual(type(result), float)
|
||||
|
||||
result = f(-1, -2, -3, -4, -5.0, -6.0)
|
||||
self.failUnlessEqual(result, -21)
|
||||
self.failUnlessEqual(type(result), float)
|
||||
|
||||
def test_doubleresult(self):
|
||||
f = dll._testfunc_d_bhilfd
|
||||
f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_double]
|
||||
f.restype = c_double
|
||||
result = f(1, 2, 3, 4, 5.0, 6.0)
|
||||
self.failUnlessEqual(result, 21)
|
||||
self.failUnlessEqual(type(result), float)
|
||||
|
||||
result = f(-1, -2, -3, -4, -5.0, -6.0)
|
||||
self.failUnlessEqual(result, -21)
|
||||
self.failUnlessEqual(type(result), float)
|
||||
|
||||
def test_longlongresult(self):
|
||||
try:
|
||||
c_longlong
|
||||
except NameError:
|
||||
return
|
||||
f = dll._testfunc_q_bhilfd
|
||||
f.restype = c_longlong
|
||||
f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_double]
|
||||
result = f(1, 2, 3, 4, 5.0, 6.0)
|
||||
self.failUnlessEqual(result, 21)
|
||||
|
||||
f = dll._testfunc_q_bhilfdq
|
||||
f.restype = c_longlong
|
||||
f.argtypes = [c_byte, c_short, c_int, c_long, c_float, c_double, c_longlong]
|
||||
result = f(1, 2, 3, 4, 5.0, 6.0, 21)
|
||||
self.failUnlessEqual(result, 42)
|
||||
|
||||
def test_stringresult(self):
|
||||
f = dll._testfunc_p_p
|
||||
f.argtypes = None
|
||||
f.restype = c_char_p
|
||||
result = f("123")
|
||||
self.failUnlessEqual(result, "123")
|
||||
|
||||
result = f(None)
|
||||
self.failUnlessEqual(result, None)
|
||||
|
||||
def test_pointers(self):
|
||||
f = dll._testfunc_p_p
|
||||
f.restype = POINTER(c_int)
|
||||
f.argtypes = [POINTER(c_int)]
|
||||
|
||||
# This only works if the value c_int(42) passed to the
|
||||
# function is still alive while the pointer (the result) is
|
||||
# used.
|
||||
|
||||
v = c_int(42)
|
||||
|
||||
self.failUnlessEqual(pointer(v).contents.value, 42)
|
||||
result = f(pointer(v))
|
||||
self.failUnlessEqual(type(result), POINTER(c_int))
|
||||
self.failUnlessEqual(result.contents.value, 42)
|
||||
|
||||
# This on works...
|
||||
result = f(pointer(v))
|
||||
self.failUnlessEqual(result.contents.value, v.value)
|
||||
|
||||
p = pointer(c_int(99))
|
||||
result = f(p)
|
||||
self.failUnlessEqual(result.contents.value, 99)
|
||||
|
||||
arg = byref(v)
|
||||
result = f(arg)
|
||||
self.failIfEqual(result.contents, v.value)
|
||||
|
||||
self.assertRaises(ArgumentError, f, byref(c_short(22)))
|
||||
|
||||
# It is dangerous, however, because you don't control the lifetime
|
||||
# of the pointer:
|
||||
result = f(byref(c_int(99)))
|
||||
self.failIfEqual(result.contents, 99)
|
||||
|
||||
def test_errors(self):
|
||||
f = dll._testfunc_p_p
|
||||
f.restype = c_int
|
||||
|
||||
class X(Structure):
|
||||
_fields_ = [("y", c_int)]
|
||||
|
||||
self.assertRaises(TypeError, f, X()) #cannot convert parameter
|
||||
|
||||
################################################################
|
||||
def test_shorts(self):
|
||||
f = dll._testfunc_callback_i_if
|
||||
|
||||
args = []
|
||||
expected = [262144, 131072, 65536, 32768, 16384, 8192, 4096, 2048,
|
||||
1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1]
|
||||
|
||||
def callback(v):
|
||||
args.append(v)
|
||||
return v
|
||||
|
||||
CallBack = CFUNCTYPE(c_int, c_int)
|
||||
|
||||
cb = CallBack(callback)
|
||||
f(2**18, cb)
|
||||
self.failUnlessEqual(args, expected)
|
||||
|
||||
################################################################
|
||||
|
||||
|
||||
def test_callbacks(self):
|
||||
f = dll._testfunc_callback_i_if
|
||||
f.restype = c_int
|
||||
|
||||
MyCallback = CFUNCTYPE(c_int, c_int)
|
||||
|
||||
def callback(value):
|
||||
#print "called back with", value
|
||||
return value
|
||||
|
||||
cb = MyCallback(callback)
|
||||
result = f(-10, cb)
|
||||
self.failUnlessEqual(result, -18)
|
||||
|
||||
# test with prototype
|
||||
f.argtypes = [c_int, MyCallback]
|
||||
cb = MyCallback(callback)
|
||||
result = f(-10, cb)
|
||||
self.failUnlessEqual(result, -18)
|
||||
|
||||
AnotherCallback = WINFUNCTYPE(c_int, c_int, c_int, c_int, c_int)
|
||||
|
||||
# check that the prototype works: we call f with wrong
|
||||
# argument types
|
||||
cb = AnotherCallback(callback)
|
||||
self.assertRaises(ArgumentError, f, -10, cb)
|
||||
|
||||
|
||||
def test_callbacks_2(self):
|
||||
# Can also use simple datatypes as argument type specifiers
|
||||
# for the callback function.
|
||||
# In this case the call receives an instance of that type
|
||||
f = dll._testfunc_callback_i_if
|
||||
f.restype = c_int
|
||||
|
||||
MyCallback = CFUNCTYPE(c_int, c_int)
|
||||
|
||||
f.argtypes = [c_int, MyCallback]
|
||||
|
||||
def callback(value):
|
||||
#print "called back with", value
|
||||
self.failUnlessEqual(type(value), int)
|
||||
return value
|
||||
|
||||
cb = MyCallback(callback)
|
||||
result = f(-10, cb)
|
||||
self.failUnlessEqual(result, -18)
|
||||
|
||||
def test_longlong_callbacks(self):
|
||||
|
||||
f = dll._testfunc_callback_q_qf
|
||||
f.restype = c_longlong
|
||||
|
||||
MyCallback = CFUNCTYPE(c_longlong, c_longlong)
|
||||
|
||||
f.argtypes = [c_longlong, MyCallback]
|
||||
|
||||
def callback(value):
|
||||
self.failUnless(isinstance(value, (int, long)))
|
||||
return value & 0x7FFFFFFF
|
||||
|
||||
cb = MyCallback(callback)
|
||||
|
||||
self.failUnlessEqual(13577625587, f(1000000000000, cb))
|
||||
|
||||
def test_errors(self):
|
||||
self.assertRaises(AttributeError, getattr, dll, "_xxx_yyy")
|
||||
self.assertRaises(ValueError, c_int.in_dll, dll, "_xxx_yyy")
|
||||
|
||||
def test_byval(self):
|
||||
|
||||
# without prototype
|
||||
ptin = POINT(1, 2)
|
||||
ptout = POINT()
|
||||
# EXPORT int _testfunc_byval(point in, point *pout)
|
||||
result = dll._testfunc_byval(ptin, byref(ptout))
|
||||
got = result, ptout.x, ptout.y
|
||||
expected = 3, 1, 2
|
||||
self.failUnlessEqual(got, expected)
|
||||
|
||||
# with prototype
|
||||
ptin = POINT(101, 102)
|
||||
ptout = POINT()
|
||||
dll._testfunc_byval.argtypes = (POINT, POINTER(POINT))
|
||||
dll._testfunc_byval.restype = c_int
|
||||
result = dll._testfunc_byval(ptin, byref(ptout))
|
||||
got = result, ptout.x, ptout.y
|
||||
expected = 203, 101, 102
|
||||
self.failUnlessEqual(got, expected)
|
||||
|
||||
def test_struct_return_2H(self):
|
||||
class S2H(Structure):
|
||||
_fields_ = [("x", c_short),
|
||||
("y", c_short)]
|
||||
dll.ret_2h_func.restype = S2H
|
||||
dll.ret_2h_func.argtypes = [S2H]
|
||||
inp = S2H(99, 88)
|
||||
s2h = dll.ret_2h_func(inp)
|
||||
self.failUnlessEqual((s2h.x, s2h.y), (99*2, 88*3))
|
||||
|
||||
if sys.platform == "win32":
|
||||
def test_struct_return_2H_stdcall(self):
|
||||
class S2H(Structure):
|
||||
_fields_ = [("x", c_short),
|
||||
("y", c_short)]
|
||||
|
||||
windll.s_ret_2h_func.restype = S2H
|
||||
windll.s_ret_2h_func.argtypes = [S2H]
|
||||
s2h = windll.s_ret_2h_func(S2H(99, 88))
|
||||
self.failUnlessEqual((s2h.x, s2h.y), (99*2, 88*3))
|
||||
|
||||
def test_struct_return_8H(self):
|
||||
class S8I(Structure):
|
||||
_fields_ = [("a", c_int),
|
||||
("b", c_int),
|
||||
("c", c_int),
|
||||
("d", c_int),
|
||||
("e", c_int),
|
||||
("f", c_int),
|
||||
("g", c_int),
|
||||
("h", c_int)]
|
||||
dll.ret_8i_func.restype = S8I
|
||||
dll.ret_8i_func.argtypes = [S8I]
|
||||
inp = S8I(9, 8, 7, 6, 5, 4, 3, 2)
|
||||
s8i = dll.ret_8i_func(inp)
|
||||
self.failUnlessEqual((s8i.a, s8i.b, s8i.c, s8i.d, s8i.e, s8i.f, s8i.g, s8i.h),
|
||||
(9*2, 8*3, 7*4, 6*5, 5*6, 4*7, 3*8, 2*9))
|
||||
|
||||
if sys.platform == "win32":
|
||||
def test_struct_return_8H_stdcall(self):
|
||||
class S8I(Structure):
|
||||
_fields_ = [("a", c_int),
|
||||
("b", c_int),
|
||||
("c", c_int),
|
||||
("d", c_int),
|
||||
("e", c_int),
|
||||
("f", c_int),
|
||||
("g", c_int),
|
||||
("h", c_int)]
|
||||
windll.s_ret_8i_func.restype = S8I
|
||||
windll.s_ret_8i_func.argtypes = [S8I]
|
||||
inp = S8I(9, 8, 7, 6, 5, 4, 3, 2)
|
||||
s8i = windll.s_ret_8i_func(inp)
|
||||
self.failUnlessEqual((s8i.a, s8i.b, s8i.c, s8i.d, s8i.e, s8i.f, s8i.g, s8i.h),
|
||||
(9*2, 8*3, 7*4, 6*5, 5*6, 4*7, 3*8, 2*9))
|
||||
|
||||
def test_sf1651235(self):
|
||||
# see http://www.python.org/sf/1651235
|
||||
|
||||
proto = CFUNCTYPE(c_int, RECT, POINT)
|
||||
def callback(*args):
|
||||
return 0
|
||||
|
||||
callback = proto(callback)
|
||||
self.failUnlessRaises(ArgumentError, lambda: callback((1, 2, 3, 4), POINT()))
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -1,42 +0,0 @@
|
|||
import unittest
|
||||
from ctypes import *
|
||||
|
||||
################################################################
|
||||
#
|
||||
# The incomplete pointer example from the tutorial
|
||||
#
|
||||
|
||||
class MyTestCase(unittest.TestCase):
|
||||
|
||||
def test_incomplete_example(self):
|
||||
lpcell = POINTER("cell")
|
||||
class cell(Structure):
|
||||
_fields_ = [("name", c_char_p),
|
||||
("next", lpcell)]
|
||||
|
||||
SetPointerType(lpcell, cell)
|
||||
|
||||
c1 = cell()
|
||||
c1.name = "foo"
|
||||
c2 = cell()
|
||||
c2.name = "bar"
|
||||
|
||||
c1.next = pointer(c2)
|
||||
c2.next = pointer(c1)
|
||||
|
||||
p = c1
|
||||
|
||||
result = []
|
||||
for i in range(8):
|
||||
result.append(p.name)
|
||||
p = p.next[0]
|
||||
self.failUnlessEqual(result, ["foo", "bar"] * 4)
|
||||
|
||||
# to not leak references, we must clean _pointer_type_cache
|
||||
from ctypes import _pointer_type_cache
|
||||
del _pointer_type_cache[cell]
|
||||
|
||||
################################################################
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -1,40 +0,0 @@
|
|||
from ctypes import *
|
||||
import unittest
|
||||
|
||||
class X(Structure):
|
||||
_fields_ = [("a", c_int),
|
||||
("b", c_int)]
|
||||
new_was_called = False
|
||||
|
||||
def __new__(cls):
|
||||
result = super(X, cls).__new__(cls)
|
||||
result.new_was_called = True
|
||||
return result
|
||||
|
||||
def __init__(self):
|
||||
self.a = 9
|
||||
self.b = 12
|
||||
|
||||
class Y(Structure):
|
||||
_fields_ = [("x", X)]
|
||||
|
||||
|
||||
class InitTest(unittest.TestCase):
|
||||
def test_get(self):
|
||||
# make sure the only accessing a nested structure
|
||||
# doesn't call the structure's __new__ and __init__
|
||||
y = Y()
|
||||
self.failUnlessEqual((y.x.a, y.x.b), (0, 0))
|
||||
self.failUnlessEqual(y.x.new_was_called, False)
|
||||
|
||||
# But explicitely creating an X structure calls __new__ and __init__, of course.
|
||||
x = X()
|
||||
self.failUnlessEqual((x.a, x.b), (9, 12))
|
||||
self.failUnlessEqual(x.new_was_called, True)
|
||||
|
||||
y.x = x
|
||||
self.failUnlessEqual((y.x.a, y.x.b), (9, 12))
|
||||
self.failUnlessEqual(y.x.new_was_called, False)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
|
@ -1,5 +0,0 @@
|
|||
# superseeded by test_numbers.py
|
||||
import unittest
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -1,103 +0,0 @@
|
|||
# This tests the internal _objects attribute
|
||||
import unittest
|
||||
from ctypes import *
|
||||
from sys import getrefcount as grc
|
||||
|
||||
# XXX This test must be reviewed for correctness!!!
|
||||
|
||||
"""
|
||||
ctypes' types are container types.
|
||||
|
||||
They have an internal memory block, which only consists of some bytes,
|
||||
but it has to keep references to other objects as well. This is not
|
||||
really needed for trivial C types like int or char, but it is important
|
||||
for aggregate types like strings or pointers in particular.
|
||||
|
||||
What about pointers?
|
||||
|
||||
"""
|
||||
|
||||
class ObjectsTestCase(unittest.TestCase):
|
||||
def failUnlessSame(self, a, b):
|
||||
self.failUnlessEqual(id(a), id(b))
|
||||
|
||||
def test_ints(self):
|
||||
i = 42000123
|
||||
self.failUnlessEqual(3, grc(i))
|
||||
ci = c_int(i)
|
||||
self.failUnlessEqual(3, grc(i))
|
||||
self.failUnlessEqual(ci._objects, None)
|
||||
|
||||
def test_c_char_p(self):
|
||||
s = "Hello, World"
|
||||
self.failUnlessEqual(3, grc(s))
|
||||
cs = c_char_p(s)
|
||||
self.failUnlessEqual(4, grc(s))
|
||||
self.failUnlessSame(cs._objects, s)
|
||||
|
||||
def test_simple_struct(self):
|
||||
class X(Structure):
|
||||
_fields_ = [("a", c_int), ("b", c_int)]
|
||||
|
||||
a = 421234
|
||||
b = 421235
|
||||
x = X()
|
||||
self.failUnlessEqual(x._objects, None)
|
||||
x.a = a
|
||||
x.b = b
|
||||
self.failUnlessEqual(x._objects, None)
|
||||
|
||||
def test_embedded_structs(self):
|
||||
class X(Structure):
|
||||
_fields_ = [("a", c_int), ("b", c_int)]
|
||||
|
||||
class Y(Structure):
|
||||
_fields_ = [("x", X), ("y", X)]
|
||||
|
||||
y = Y()
|
||||
self.failUnlessEqual(y._objects, None)
|
||||
|
||||
x1, x2 = X(), X()
|
||||
y.x, y.y = x1, x2
|
||||
self.failUnlessEqual(y._objects, {"0": {}, "1": {}})
|
||||
x1.a, x2.b = 42, 93
|
||||
self.failUnlessEqual(y._objects, {"0": {}, "1": {}})
|
||||
|
||||
def test_xxx(self):
|
||||
class X(Structure):
|
||||
_fields_ = [("a", c_char_p), ("b", c_char_p)]
|
||||
|
||||
class Y(Structure):
|
||||
_fields_ = [("x", X), ("y", X)]
|
||||
|
||||
s1 = "Hello, World"
|
||||
s2 = "Hallo, Welt"
|
||||
|
||||
x = X()
|
||||
x.a = s1
|
||||
x.b = s2
|
||||
self.failUnlessEqual(x._objects, {"0": s1, "1": s2})
|
||||
|
||||
y = Y()
|
||||
y.x = x
|
||||
self.failUnlessEqual(y._objects, {"0": {"0": s1, "1": s2}})
|
||||
## x = y.x
|
||||
## del y
|
||||
## print x._b_base_._objects
|
||||
|
||||
def test_ptr_struct(self):
|
||||
class X(Structure):
|
||||
_fields_ = [("data", POINTER(c_int))]
|
||||
|
||||
A = c_int*4
|
||||
a = A(11, 22, 33, 44)
|
||||
self.failUnlessEqual(a._objects, None)
|
||||
|
||||
x = X()
|
||||
x.data = a
|
||||
##XXX print x._objects
|
||||
##XXX print x.data[0]
|
||||
##XXX print x.data._objects
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -1,152 +0,0 @@
|
|||
from ctypes import *
|
||||
import unittest
|
||||
|
||||
class SimpleTestCase(unittest.TestCase):
|
||||
def test_cint(self):
|
||||
x = c_int()
|
||||
self.assertEquals(x._objects, None)
|
||||
x.value = 42
|
||||
self.assertEquals(x._objects, None)
|
||||
x = c_int(99)
|
||||
self.assertEquals(x._objects, None)
|
||||
|
||||
def test_ccharp(self):
|
||||
x = c_char_p()
|
||||
self.assertEquals(x._objects, None)
|
||||
x.value = "abc"
|
||||
self.assertEquals(x._objects, "abc")
|
||||
x = c_char_p("spam")
|
||||
self.assertEquals(x._objects, "spam")
|
||||
|
||||
class StructureTestCase(unittest.TestCase):
|
||||
def test_cint_struct(self):
|
||||
class X(Structure):
|
||||
_fields_ = [("a", c_int),
|
||||
("b", c_int)]
|
||||
|
||||
x = X()
|
||||
self.assertEquals(x._objects, None)
|
||||
x.a = 42
|
||||
x.b = 99
|
||||
self.assertEquals(x._objects, None)
|
||||
|
||||
def test_ccharp_struct(self):
|
||||
class X(Structure):
|
||||
_fields_ = [("a", c_char_p),
|
||||
("b", c_char_p)]
|
||||
x = X()
|
||||
self.assertEquals(x._objects, None)
|
||||
|
||||
x.a = "spam"
|
||||
x.b = "foo"
|
||||
self.assertEquals(x._objects, {"0": "spam", "1": "foo"})
|
||||
|
||||
def test_struct_struct(self):
|
||||
class POINT(Structure):
|
||||
_fields_ = [("x", c_int), ("y", c_int)]
|
||||
class RECT(Structure):
|
||||
_fields_ = [("ul", POINT), ("lr", POINT)]
|
||||
|
||||
r = RECT()
|
||||
r.ul.x = 0
|
||||
r.ul.y = 1
|
||||
r.lr.x = 2
|
||||
r.lr.y = 3
|
||||
self.assertEquals(r._objects, None)
|
||||
|
||||
r = RECT()
|
||||
pt = POINT(1, 2)
|
||||
r.ul = pt
|
||||
self.assertEquals(r._objects, {'0': {}})
|
||||
r.ul.x = 22
|
||||
r.ul.y = 44
|
||||
self.assertEquals(r._objects, {'0': {}})
|
||||
r.lr = POINT()
|
||||
self.assertEquals(r._objects, {'0': {}, '1': {}})
|
||||
|
||||
class ArrayTestCase(unittest.TestCase):
|
||||
def test_cint_array(self):
|
||||
INTARR = c_int * 3
|
||||
|
||||
ia = INTARR()
|
||||
self.assertEquals(ia._objects, None)
|
||||
ia[0] = 1
|
||||
ia[1] = 2
|
||||
ia[2] = 3
|
||||
self.assertEquals(ia._objects, None)
|
||||
|
||||
class X(Structure):
|
||||
_fields_ = [("x", c_int),
|
||||
("a", INTARR)]
|
||||
|
||||
x = X()
|
||||
x.x = 1000
|
||||
x.a[0] = 42
|
||||
x.a[1] = 96
|
||||
self.assertEquals(x._objects, None)
|
||||
x.a = ia
|
||||
self.assertEquals(x._objects, {'1': {}})
|
||||
|
||||
class PointerTestCase(unittest.TestCase):
|
||||
def test_p_cint(self):
|
||||
i = c_int(42)
|
||||
x = pointer(i)
|
||||
self.failUnlessEqual(x._objects, {'1': i})
|
||||
|
||||
class DeletePointerTestCase(unittest.TestCase):
|
||||
def X_test(self):
|
||||
class X(Structure):
|
||||
_fields_ = [("p", POINTER(c_char_p))]
|
||||
x = X()
|
||||
i = c_char_p("abc def")
|
||||
from sys import getrefcount as grc
|
||||
print "2?", grc(i)
|
||||
x.p = pointer(i)
|
||||
print "3?", grc(i)
|
||||
for i in range(320):
|
||||
c_int(99)
|
||||
x.p[0]
|
||||
print x.p[0]
|
||||
## del x
|
||||
## print "2?", grc(i)
|
||||
## del i
|
||||
import gc
|
||||
gc.collect()
|
||||
for i in range(320):
|
||||
c_int(99)
|
||||
x.p[0]
|
||||
print x.p[0]
|
||||
print x.p.contents
|
||||
## print x._objects
|
||||
|
||||
x.p[0] = "spam spam"
|
||||
## print x.p[0]
|
||||
print "+" * 42
|
||||
print x._objects
|
||||
|
||||
class PointerToStructure(unittest.TestCase):
|
||||
def test(self):
|
||||
class POINT(Structure):
|
||||
_fields_ = [("x", c_int), ("y", c_int)]
|
||||
class RECT(Structure):
|
||||
_fields_ = [("a", POINTER(POINT)),
|
||||
("b", POINTER(POINT))]
|
||||
r = RECT()
|
||||
p1 = POINT(1, 2)
|
||||
|
||||
r.a = pointer(p1)
|
||||
r.b = pointer(p1)
|
||||
## from pprint import pprint as pp
|
||||
## pp(p1._objects)
|
||||
## pp(r._objects)
|
||||
|
||||
r.a[0].x = 42
|
||||
r.a[0].y = 99
|
||||
|
||||
# to avoid leaking when tests are run several times
|
||||
# clean up the types left in the cache.
|
||||
from ctypes import _pointer_type_cache
|
||||
del _pointer_type_cache[POINT]
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
|
@ -1,30 +0,0 @@
|
|||
import sys, os
|
||||
import unittest
|
||||
|
||||
from ctypes import *
|
||||
import _ctypes_test
|
||||
|
||||
lib = CDLL(_ctypes_test.__file__)
|
||||
|
||||
class LibTest(unittest.TestCase):
|
||||
def test_sqrt(self):
|
||||
lib.my_sqrt.argtypes = c_double,
|
||||
lib.my_sqrt.restype = c_double
|
||||
self.failUnlessEqual(lib.my_sqrt(4.0), 2.0)
|
||||
import math
|
||||
self.failUnlessEqual(lib.my_sqrt(2.0), math.sqrt(2.0))
|
||||
|
||||
def test_qsort(self):
|
||||
comparefunc = CFUNCTYPE(c_int, POINTER(c_char), POINTER(c_char))
|
||||
lib.my_qsort.argtypes = c_void_p, c_size_t, c_size_t, comparefunc
|
||||
lib.my_qsort.restype = None
|
||||
|
||||
def sort(a, b):
|
||||
return cmp(a[0], b[0])
|
||||
|
||||
chars = create_string_buffer("spam, spam, and spam")
|
||||
lib.my_qsort(chars, len(chars)-1, sizeof(c_char), comparefunc(sort))
|
||||
self.failUnlessEqual(chars.raw, " ,,aaaadmmmnpppsss\x00")
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
|
@ -1,78 +0,0 @@
|
|||
from ctypes import *
|
||||
import sys, unittest
|
||||
import os, StringIO
|
||||
from ctypes.util import find_library
|
||||
from ctypes.test import is_resource_enabled
|
||||
|
||||
libc_name = None
|
||||
if os.name == "nt":
|
||||
libc_name = "msvcrt"
|
||||
elif os.name == "ce":
|
||||
libc_name = "coredll"
|
||||
elif sys.platform == "cygwin":
|
||||
libc_name = "cygwin1.dll"
|
||||
else:
|
||||
libc_name = find_library("c")
|
||||
|
||||
if True or is_resource_enabled("printing"):
|
||||
print >> sys.stderr, "\tfind_library('c') -> ", find_library('c')
|
||||
print >> sys.stderr, "\tfind_library('m') -> ", find_library('m')
|
||||
|
||||
class LoaderTest(unittest.TestCase):
|
||||
|
||||
unknowndll = "xxrandomnamexx"
|
||||
|
||||
if libc_name is not None:
|
||||
def test_load(self):
|
||||
CDLL(libc_name)
|
||||
CDLL(os.path.basename(libc_name))
|
||||
self.assertRaises(OSError, CDLL, self.unknowndll)
|
||||
|
||||
if libc_name is not None and os.path.basename(libc_name) == "libc.so.6":
|
||||
def test_load_version(self):
|
||||
cdll.LoadLibrary("libc.so.6")
|
||||
# linux uses version, libc 9 should not exist
|
||||
self.assertRaises(OSError, cdll.LoadLibrary, "libc.so.9")
|
||||
self.assertRaises(OSError, cdll.LoadLibrary, self.unknowndll)
|
||||
|
||||
def test_find(self):
|
||||
for name in ("c", "m"):
|
||||
lib = find_library(name)
|
||||
if lib:
|
||||
cdll.LoadLibrary(lib)
|
||||
CDLL(lib)
|
||||
|
||||
if os.name in ("nt", "ce"):
|
||||
def test_load_library(self):
|
||||
if is_resource_enabled("printing"):
|
||||
print find_library("kernel32")
|
||||
print find_library("user32")
|
||||
|
||||
if os.name == "nt":
|
||||
windll.kernel32.GetModuleHandleW
|
||||
windll["kernel32"].GetModuleHandleW
|
||||
windll.LoadLibrary("kernel32").GetModuleHandleW
|
||||
WinDLL("kernel32").GetModuleHandleW
|
||||
elif os.name == "ce":
|
||||
windll.coredll.GetModuleHandleW
|
||||
windll["coredll"].GetModuleHandleW
|
||||
windll.LoadLibrary("coredll").GetModuleHandleW
|
||||
WinDLL("coredll").GetModuleHandleW
|
||||
|
||||
def test_load_ordinal_functions(self):
|
||||
import _ctypes_test
|
||||
dll = WinDLL(_ctypes_test.__file__)
|
||||
# We load the same function both via ordinal and name
|
||||
func_ord = dll[2]
|
||||
func_name = dll.GetString
|
||||
# addressof gets the address where the function pointer is stored
|
||||
a_ord = addressof(func_ord)
|
||||
a_name = addressof(func_name)
|
||||
f_ord_addr = c_void_p.from_address(a_ord).value
|
||||
f_name_addr = c_void_p.from_address(a_name).value
|
||||
self.failUnlessEqual(hex(f_ord_addr), hex(f_name_addr))
|
||||
|
||||
self.failUnlessRaises(AttributeError, dll.__getitem__, 1234)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
|
@ -1,62 +0,0 @@
|
|||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
# Bob Ippolito:
|
||||
"""
|
||||
Ok.. the code to find the filename for __getattr__ should look
|
||||
something like:
|
||||
|
||||
import os
|
||||
from macholib.dyld import dyld_find
|
||||
|
||||
def find_lib(name):
|
||||
possible = ['lib'+name+'.dylib', name+'.dylib',
|
||||
name+'.framework/'+name]
|
||||
for dylib in possible:
|
||||
try:
|
||||
return os.path.realpath(dyld_find(dylib))
|
||||
except ValueError:
|
||||
pass
|
||||
raise ValueError, "%s not found" % (name,)
|
||||
|
||||
It'll have output like this:
|
||||
|
||||
>>> find_lib('pthread')
|
||||
'/usr/lib/libSystem.B.dylib'
|
||||
>>> find_lib('z')
|
||||
'/usr/lib/libz.1.dylib'
|
||||
>>> find_lib('IOKit')
|
||||
'/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit'
|
||||
|
||||
-bob
|
||||
|
||||
"""
|
||||
|
||||
from ctypes.macholib.dyld import dyld_find
|
||||
|
||||
def find_lib(name):
|
||||
possible = ['lib'+name+'.dylib', name+'.dylib', name+'.framework/'+name]
|
||||
for dylib in possible:
|
||||
try:
|
||||
return os.path.realpath(dyld_find(dylib))
|
||||
except ValueError:
|
||||
pass
|
||||
raise ValueError, "%s not found" % (name,)
|
||||
|
||||
class MachOTest(unittest.TestCase):
|
||||
if sys.platform == "darwin":
|
||||
def test_find(self):
|
||||
|
||||
self.failUnlessEqual(find_lib('pthread'),
|
||||
'/usr/lib/libSystem.B.dylib')
|
||||
|
||||
result = find_lib('z')
|
||||
self.failUnless(result.startswith('/usr/lib/libz.1'))
|
||||
self.failUnless(result.endswith('.dylib'))
|
||||
|
||||
self.failUnlessEqual(find_lib('IOKit'),
|
||||
'/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit')
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
|
@ -1,61 +0,0 @@
|
|||
import sys
|
||||
import unittest
|
||||
from ctypes import *
|
||||
|
||||
class MemFunctionsTest(unittest.TestCase):
|
||||
def test_memmove(self):
|
||||
# large buffers apparently increase the chance that the memory
|
||||
# is allocated in high address space.
|
||||
a = create_string_buffer(1000000)
|
||||
p = "Hello, World"
|
||||
result = memmove(a, p, len(p))
|
||||
self.failUnlessEqual(a.value, "Hello, World")
|
||||
|
||||
self.failUnlessEqual(string_at(result), "Hello, World")
|
||||
self.failUnlessEqual(string_at(result, 5), "Hello")
|
||||
self.failUnlessEqual(string_at(result, 16), "Hello, World\0\0\0\0")
|
||||
self.failUnlessEqual(string_at(result, 0), "")
|
||||
|
||||
def test_memset(self):
|
||||
a = create_string_buffer(1000000)
|
||||
result = memset(a, ord('x'), 16)
|
||||
self.failUnlessEqual(a.value, "xxxxxxxxxxxxxxxx")
|
||||
|
||||
self.failUnlessEqual(string_at(result), "xxxxxxxxxxxxxxxx")
|
||||
self.failUnlessEqual(string_at(a), "xxxxxxxxxxxxxxxx")
|
||||
self.failUnlessEqual(string_at(a, 20), "xxxxxxxxxxxxxxxx\0\0\0\0")
|
||||
|
||||
def test_cast(self):
|
||||
a = (c_ubyte * 32)(*map(ord, "abcdef"))
|
||||
self.failUnlessEqual(cast(a, c_char_p).value, "abcdef")
|
||||
self.failUnlessEqual(cast(a, POINTER(c_byte))[:7],
|
||||
[97, 98, 99, 100, 101, 102, 0])
|
||||
|
||||
def test_string_at(self):
|
||||
s = string_at("foo bar")
|
||||
# XXX The following may be wrong, depending on how Python
|
||||
# manages string instances
|
||||
self.failUnlessEqual(2, sys.getrefcount(s))
|
||||
self.failUnless(s, "foo bar")
|
||||
|
||||
self.failUnlessEqual(string_at("foo bar", 8), "foo bar\0")
|
||||
self.failUnlessEqual(string_at("foo bar", 3), "foo")
|
||||
|
||||
try:
|
||||
create_unicode_buffer
|
||||
except NameError:
|
||||
pass
|
||||
else:
|
||||
def test_wstring_at(self):
|
||||
p = create_unicode_buffer("Hello, World")
|
||||
a = create_unicode_buffer(1000000)
|
||||
result = memmove(a, p, len(p) * sizeof(c_wchar))
|
||||
self.failUnlessEqual(a.value, "Hello, World")
|
||||
|
||||
self.failUnlessEqual(wstring_at(a), "Hello, World")
|
||||
self.failUnlessEqual(wstring_at(a, 5), "Hello")
|
||||
self.failUnlessEqual(wstring_at(a, 16), "Hello, World\0\0\0\0")
|
||||
self.failUnlessEqual(wstring_at(a, 0), "")
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
|
@ -1,230 +0,0 @@
|
|||
from ctypes import *
|
||||
import unittest
|
||||
import sys, struct
|
||||
|
||||
def valid_ranges(*types):
|
||||
# given a sequence of numeric types, collect their _type_
|
||||
# attribute, which is a single format character compatible with
|
||||
# the struct module, use the struct module to calculate the
|
||||
# minimum and maximum value allowed for this format.
|
||||
# Returns a list of (min, max) values.
|
||||
result = []
|
||||
for t in types:
|
||||
fmt = t._type_
|
||||
size = struct.calcsize(fmt)
|
||||
a = struct.unpack(fmt, ("\x00"*32)[:size])[0]
|
||||
b = struct.unpack(fmt, ("\xFF"*32)[:size])[0]
|
||||
c = struct.unpack(fmt, ("\x7F"+"\x00"*32)[:size])[0]
|
||||
d = struct.unpack(fmt, ("\x80"+"\xFF"*32)[:size])[0]
|
||||
result.append((min(a, b, c, d), max(a, b, c, d)))
|
||||
return result
|
||||
|
||||
ArgType = type(byref(c_int(0)))
|
||||
|
||||
unsigned_types = [c_ubyte, c_ushort, c_uint, c_ulong]
|
||||
signed_types = [c_byte, c_short, c_int, c_long, c_longlong]
|
||||
|
||||
float_types = [c_double, c_float]
|
||||
|
||||
try:
|
||||
c_ulonglong
|
||||
c_longlong
|
||||
except NameError:
|
||||
pass
|
||||
else:
|
||||
unsigned_types.append(c_ulonglong)
|
||||
signed_types.append(c_longlong)
|
||||
|
||||
unsigned_ranges = valid_ranges(*unsigned_types)
|
||||
signed_ranges = valid_ranges(*signed_types)
|
||||
|
||||
################################################################
|
||||
|
||||
class NumberTestCase(unittest.TestCase):
|
||||
|
||||
def test_default_init(self):
|
||||
# default values are set to zero
|
||||
for t in signed_types + unsigned_types + float_types:
|
||||
self.failUnlessEqual(t().value, 0)
|
||||
|
||||
def test_unsigned_values(self):
|
||||
# the value given to the constructor is available
|
||||
# as the 'value' attribute
|
||||
for t, (l, h) in zip(unsigned_types, unsigned_ranges):
|
||||
self.failUnlessEqual(t(l).value, l)
|
||||
self.failUnlessEqual(t(h).value, h)
|
||||
|
||||
def test_signed_values(self):
|
||||
# see above
|
||||
for t, (l, h) in zip(signed_types, signed_ranges):
|
||||
self.failUnlessEqual(t(l).value, l)
|
||||
self.failUnlessEqual(t(h).value, h)
|
||||
|
||||
def test_typeerror(self):
|
||||
# Only numbers are allowed in the contructor,
|
||||
# otherwise TypeError is raised
|
||||
for t in signed_types + unsigned_types + float_types:
|
||||
self.assertRaises(TypeError, t, "")
|
||||
self.assertRaises(TypeError, t, None)
|
||||
|
||||
## def test_valid_ranges(self):
|
||||
## # invalid values of the correct type
|
||||
## # raise ValueError (not OverflowError)
|
||||
## for t, (l, h) in zip(unsigned_types, unsigned_ranges):
|
||||
## self.assertRaises(ValueError, t, l-1)
|
||||
## self.assertRaises(ValueError, t, h+1)
|
||||
|
||||
def test_from_param(self):
|
||||
# the from_param class method attribute always
|
||||
# returns PyCArgObject instances
|
||||
for t in signed_types + unsigned_types + float_types:
|
||||
self.failUnlessEqual(ArgType, type(t.from_param(0)))
|
||||
|
||||
def test_byref(self):
|
||||
# calling byref returns also a PyCArgObject instance
|
||||
for t in signed_types + unsigned_types + float_types:
|
||||
parm = byref(t())
|
||||
self.failUnlessEqual(ArgType, type(parm))
|
||||
|
||||
|
||||
def test_floats(self):
|
||||
# c_float and c_double can be created from
|
||||
# Python int, long and float
|
||||
for t in float_types:
|
||||
self.failUnlessEqual(t(2.0).value, 2.0)
|
||||
self.failUnlessEqual(t(2).value, 2.0)
|
||||
self.failUnlessEqual(t(2L).value, 2.0)
|
||||
|
||||
def test_integers(self):
|
||||
# integers cannot be constructed from floats
|
||||
for t in signed_types + unsigned_types:
|
||||
self.assertRaises(TypeError, t, 3.14)
|
||||
|
||||
def test_sizes(self):
|
||||
for t in signed_types + unsigned_types + float_types:
|
||||
size = struct.calcsize(t._type_)
|
||||
# sizeof of the type...
|
||||
self.failUnlessEqual(sizeof(t), size)
|
||||
# and sizeof of an instance
|
||||
self.failUnlessEqual(sizeof(t()), size)
|
||||
|
||||
def test_alignments(self):
|
||||
for t in signed_types + unsigned_types + float_types:
|
||||
code = t._type_ # the typecode
|
||||
align = struct.calcsize("c%c" % code) - struct.calcsize(code)
|
||||
|
||||
# alignment of the type...
|
||||
self.failUnlessEqual((code, alignment(t)),
|
||||
(code, align))
|
||||
# and alignment of an instance
|
||||
self.failUnlessEqual((code, alignment(t())),
|
||||
(code, align))
|
||||
|
||||
def test_int_from_address(self):
|
||||
from array import array
|
||||
for t in signed_types + unsigned_types:
|
||||
# the array module doesn't suppport all format codes
|
||||
# (no 'q' or 'Q')
|
||||
try:
|
||||
array(t._type_)
|
||||
except ValueError:
|
||||
continue
|
||||
a = array(t._type_, [100])
|
||||
|
||||
# v now is an integer at an 'external' memory location
|
||||
v = t.from_address(a.buffer_info()[0])
|
||||
self.failUnlessEqual(v.value, a[0])
|
||||
self.failUnlessEqual(type(v), t)
|
||||
|
||||
# changing the value at the memory location changes v's value also
|
||||
a[0] = 42
|
||||
self.failUnlessEqual(v.value, a[0])
|
||||
|
||||
|
||||
def test_float_from_address(self):
|
||||
from array import array
|
||||
for t in float_types:
|
||||
a = array(t._type_, [3.14])
|
||||
v = t.from_address(a.buffer_info()[0])
|
||||
self.failUnlessEqual(v.value, a[0])
|
||||
self.failUnless(type(v) is t)
|
||||
a[0] = 2.3456e17
|
||||
self.failUnlessEqual(v.value, a[0])
|
||||
self.failUnless(type(v) is t)
|
||||
|
||||
def test_char_from_address(self):
|
||||
from ctypes import c_char
|
||||
from array import array
|
||||
|
||||
a = array('c', 'x')
|
||||
v = c_char.from_address(a.buffer_info()[0])
|
||||
self.failUnlessEqual(v.value, a[0])
|
||||
self.failUnless(type(v) is c_char)
|
||||
|
||||
a[0] = '?'
|
||||
self.failUnlessEqual(v.value, a[0])
|
||||
|
||||
def test_init(self):
|
||||
# c_int() can be initialized from Python's int, and c_int.
|
||||
# Not from c_long or so, which seems strange, abd should
|
||||
# probably be changed:
|
||||
self.assertRaises(TypeError, c_int, c_long(42))
|
||||
|
||||
## def test_perf(self):
|
||||
## check_perf()
|
||||
|
||||
from ctypes import _SimpleCData
|
||||
class c_int_S(_SimpleCData):
|
||||
_type_ = "i"
|
||||
__slots__ = []
|
||||
|
||||
def run_test(rep, msg, func, arg=None):
|
||||
## items = [None] * rep
|
||||
items = range(rep)
|
||||
from time import clock
|
||||
if arg is not None:
|
||||
start = clock()
|
||||
for i in items:
|
||||
func(arg); func(arg); func(arg); func(arg); func(arg)
|
||||
stop = clock()
|
||||
else:
|
||||
start = clock()
|
||||
for i in items:
|
||||
func(); func(); func(); func(); func()
|
||||
stop = clock()
|
||||
print "%15s: %.2f us" % (msg, ((stop-start)*1e6/5/rep))
|
||||
|
||||
def check_perf():
|
||||
# Construct 5 objects
|
||||
from ctypes import c_int
|
||||
|
||||
REP = 200000
|
||||
|
||||
run_test(REP, "int()", int)
|
||||
run_test(REP, "int(999)", int)
|
||||
run_test(REP, "c_int()", c_int)
|
||||
run_test(REP, "c_int(999)", c_int)
|
||||
run_test(REP, "c_int_S()", c_int_S)
|
||||
run_test(REP, "c_int_S(999)", c_int_S)
|
||||
|
||||
# Python 2.3 -OO, win2k, P4 700 MHz:
|
||||
#
|
||||
# int(): 0.87 us
|
||||
# int(999): 0.87 us
|
||||
# c_int(): 3.35 us
|
||||
# c_int(999): 3.34 us
|
||||
# c_int_S(): 3.23 us
|
||||
# c_int_S(999): 3.24 us
|
||||
|
||||
# Python 2.2 -OO, win2k, P4 700 MHz:
|
||||
#
|
||||
# int(): 0.89 us
|
||||
# int(999): 0.89 us
|
||||
# c_int(): 9.99 us
|
||||
# c_int(999): 10.02 us
|
||||
# c_int_S(): 9.87 us
|
||||
# c_int_S(999): 9.85 us
|
||||
|
||||
if __name__ == '__main__':
|
||||
## check_perf()
|
||||
unittest.main()
|
|
@ -1,70 +0,0 @@
|
|||
r'''
|
||||
This tests the '_objects' attribute of ctypes instances. '_objects'
|
||||
holds references to objects that must be kept alive as long as the
|
||||
ctypes instance, to make sure that the memory buffer is valid.
|
||||
|
||||
WARNING: The '_objects' attribute is exposed ONLY for debugging ctypes itself,
|
||||
it MUST NEVER BE MODIFIED!
|
||||
|
||||
'_objects' is initialized to a dictionary on first use, before that it
|
||||
is None.
|
||||
|
||||
Here is an array of string pointers:
|
||||
|
||||
>>> from ctypes import *
|
||||
>>> array = (c_char_p * 5)()
|
||||
>>> print array._objects
|
||||
None
|
||||
>>>
|
||||
|
||||
The memory block stores pointers to strings, and the strings itself
|
||||
assigned from Python must be kept.
|
||||
|
||||
>>> array[4] = 'foo bar'
|
||||
>>> array._objects
|
||||
{'4': 'foo bar'}
|
||||
>>> array[4]
|
||||
'foo bar'
|
||||
>>>
|
||||
|
||||
It gets more complicated when the ctypes instance itself is contained
|
||||
in a 'base' object.
|
||||
|
||||
>>> class X(Structure):
|
||||
... _fields_ = [("x", c_int), ("y", c_int), ("array", c_char_p * 5)]
|
||||
...
|
||||
>>> x = X()
|
||||
>>> print x._objects
|
||||
None
|
||||
>>>
|
||||
|
||||
The'array' attribute of the 'x' object shares part of the memory buffer
|
||||
of 'x' ('_b_base_' is either None, or the root object owning the memory block):
|
||||
|
||||
>>> print x.array._b_base_ # doctest: +ELLIPSIS
|
||||
<ctypes.test.test_objects.X object at 0x...>
|
||||
>>>
|
||||
|
||||
>>> x.array[0] = 'spam spam spam'
|
||||
>>> x._objects
|
||||
{'0:2': 'spam spam spam'}
|
||||
>>> x.array._b_base_._objects
|
||||
{'0:2': 'spam spam spam'}
|
||||
>>>
|
||||
|
||||
'''
|
||||
|
||||
import unittest, doctest, sys
|
||||
|
||||
import ctypes.test.test_objects
|
||||
|
||||
class TestCase(unittest.TestCase):
|
||||
if sys.hexversion > 0x02040000:
|
||||
# Python 2.3 has no ELLIPSIS flag, so we don't test with this
|
||||
# version:
|
||||
def test(self):
|
||||
doctest.testmod(ctypes.test.test_objects)
|
||||
|
||||
if __name__ == '__main__':
|
||||
if sys.hexversion > 0x02040000:
|
||||
doctest.testmod(ctypes.test.test_objects)
|
|
@ -1,188 +0,0 @@
|
|||
import unittest, sys
|
||||
|
||||
class SimpleTypesTestCase(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
import ctypes
|
||||
try:
|
||||
from _ctypes import set_conversion_mode
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
self.prev_conv_mode = set_conversion_mode("ascii", "strict")
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
from _ctypes import set_conversion_mode
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
set_conversion_mode(*self.prev_conv_mode)
|
||||
|
||||
|
||||
def test_subclasses(self):
|
||||
from ctypes import c_void_p, c_char_p
|
||||
# ctypes 0.9.5 and before did overwrite from_param in SimpleType_new
|
||||
class CVOIDP(c_void_p):
|
||||
def from_param(cls, value):
|
||||
return value * 2
|
||||
from_param = classmethod(from_param)
|
||||
|
||||
class CCHARP(c_char_p):
|
||||
def from_param(cls, value):
|
||||
return value * 4
|
||||
from_param = classmethod(from_param)
|
||||
|
||||
self.failUnlessEqual(CVOIDP.from_param("abc"), "abcabc")
|
||||
self.failUnlessEqual(CCHARP.from_param("abc"), "abcabcabcabc")
|
||||
|
||||
try:
|
||||
from ctypes import c_wchar_p
|
||||
except ImportError:
|
||||
return
|
||||
|
||||
class CWCHARP(c_wchar_p):
|
||||
def from_param(cls, value):
|
||||
return value * 3
|
||||
from_param = classmethod(from_param)
|
||||
|
||||
self.failUnlessEqual(CWCHARP.from_param("abc"), "abcabcabc")
|
||||
|
||||
# XXX Replace by c_char_p tests
|
||||
def test_cstrings(self):
|
||||
from ctypes import c_char_p, byref
|
||||
|
||||
# c_char_p.from_param on a Python String packs the string
|
||||
# into a cparam object
|
||||
s = "123"
|
||||
self.failUnless(c_char_p.from_param(s)._obj is s)
|
||||
|
||||
# new in 0.9.1: convert (encode) unicode to ascii
|
||||
self.failUnlessEqual(c_char_p.from_param(u"123")._obj, "123")
|
||||
self.assertRaises(UnicodeEncodeError, c_char_p.from_param, u"123\377")
|
||||
|
||||
self.assertRaises(TypeError, c_char_p.from_param, 42)
|
||||
|
||||
# calling c_char_p.from_param with a c_char_p instance
|
||||
# returns the argument itself:
|
||||
a = c_char_p("123")
|
||||
self.failUnless(c_char_p.from_param(a) is a)
|
||||
|
||||
def test_cw_strings(self):
|
||||
from ctypes import byref
|
||||
try:
|
||||
from ctypes import c_wchar_p
|
||||
except ImportError:
|
||||
## print "(No c_wchar_p)"
|
||||
return
|
||||
s = u"123"
|
||||
if sys.platform == "win32":
|
||||
self.failUnless(c_wchar_p.from_param(s)._obj is s)
|
||||
self.assertRaises(TypeError, c_wchar_p.from_param, 42)
|
||||
|
||||
# new in 0.9.1: convert (decode) ascii to unicode
|
||||
self.failUnlessEqual(c_wchar_p.from_param("123")._obj, u"123")
|
||||
self.assertRaises(UnicodeDecodeError, c_wchar_p.from_param, "123\377")
|
||||
|
||||
pa = c_wchar_p.from_param(c_wchar_p(u"123"))
|
||||
self.failUnlessEqual(type(pa), c_wchar_p)
|
||||
|
||||
def test_int_pointers(self):
|
||||
from ctypes import c_short, c_uint, c_int, c_long, POINTER, pointer
|
||||
LPINT = POINTER(c_int)
|
||||
|
||||
## p = pointer(c_int(42))
|
||||
## x = LPINT.from_param(p)
|
||||
x = LPINT.from_param(pointer(c_int(42)))
|
||||
self.failUnlessEqual(x.contents.value, 42)
|
||||
self.failUnlessEqual(LPINT(c_int(42)).contents.value, 42)
|
||||
|
||||
self.failUnlessEqual(LPINT.from_param(None), 0)
|
||||
|
||||
if c_int != c_long:
|
||||
self.assertRaises(TypeError, LPINT.from_param, pointer(c_long(42)))
|
||||
self.assertRaises(TypeError, LPINT.from_param, pointer(c_uint(42)))
|
||||
self.assertRaises(TypeError, LPINT.from_param, pointer(c_short(42)))
|
||||
|
||||
def test_byref_pointer(self):
|
||||
# The from_param class method of POINTER(typ) classes accepts what is
|
||||
# returned by byref(obj), it type(obj) == typ
|
||||
from ctypes import c_short, c_uint, c_int, c_long, pointer, POINTER, byref
|
||||
LPINT = POINTER(c_int)
|
||||
|
||||
LPINT.from_param(byref(c_int(42)))
|
||||
|
||||
self.assertRaises(TypeError, LPINT.from_param, byref(c_short(22)))
|
||||
if c_int != c_long:
|
||||
self.assertRaises(TypeError, LPINT.from_param, byref(c_long(22)))
|
||||
self.assertRaises(TypeError, LPINT.from_param, byref(c_uint(22)))
|
||||
|
||||
def test_byref_pointerpointer(self):
|
||||
# See above
|
||||
from ctypes import c_short, c_uint, c_int, c_long, pointer, POINTER, byref
|
||||
|
||||
LPLPINT = POINTER(POINTER(c_int))
|
||||
LPLPINT.from_param(byref(pointer(c_int(42))))
|
||||
|
||||
self.assertRaises(TypeError, LPLPINT.from_param, byref(pointer(c_short(22))))
|
||||
if c_int != c_long:
|
||||
self.assertRaises(TypeError, LPLPINT.from_param, byref(pointer(c_long(22))))
|
||||
self.assertRaises(TypeError, LPLPINT.from_param, byref(pointer(c_uint(22))))
|
||||
|
||||
def test_array_pointers(self):
|
||||
from ctypes import c_short, c_uint, c_int, c_long, POINTER
|
||||
INTARRAY = c_int * 3
|
||||
ia = INTARRAY()
|
||||
self.failUnlessEqual(len(ia), 3)
|
||||
self.failUnlessEqual([ia[i] for i in range(3)], [0, 0, 0])
|
||||
|
||||
# Pointers are only compatible with arrays containing items of
|
||||
# the same type!
|
||||
LPINT = POINTER(c_int)
|
||||
LPINT.from_param((c_int*3)())
|
||||
self.assertRaises(TypeError, LPINT.from_param, c_short*3)
|
||||
self.assertRaises(TypeError, LPINT.from_param, c_long*3)
|
||||
self.assertRaises(TypeError, LPINT.from_param, c_uint*3)
|
||||
|
||||
## def test_performance(self):
|
||||
## check_perf()
|
||||
|
||||
def test_noctypes_argtype(self):
|
||||
import _ctypes_test
|
||||
from ctypes import CDLL, c_void_p, ArgumentError
|
||||
|
||||
func = CDLL(_ctypes_test.__file__)._testfunc_p_p
|
||||
func.restype = c_void_p
|
||||
# TypeError: has no from_param method
|
||||
self.assertRaises(TypeError, setattr, func, "argtypes", (object,))
|
||||
|
||||
class Adapter(object):
|
||||
def from_param(cls, obj):
|
||||
return None
|
||||
|
||||
func.argtypes = (Adapter(),)
|
||||
self.failUnlessEqual(func(None), None)
|
||||
self.failUnlessEqual(func(object()), None)
|
||||
|
||||
class Adapter(object):
|
||||
def from_param(cls, obj):
|
||||
return obj
|
||||
|
||||
func.argtypes = (Adapter(),)
|
||||
# don't know how to convert parameter 1
|
||||
self.assertRaises(ArgumentError, func, object())
|
||||
self.failUnlessEqual(func(c_void_p(42)), 42)
|
||||
|
||||
class Adapter(object):
|
||||
def from_param(cls, obj):
|
||||
raise ValueError(obj)
|
||||
|
||||
func.argtypes = (Adapter(),)
|
||||
# ArgumentError: argument 1: ValueError: 99
|
||||
self.assertRaises(ArgumentError, func, 99)
|
||||
|
||||
|
||||
################################################################
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -1,179 +0,0 @@
|
|||
import unittest
|
||||
|
||||
from ctypes import *
|
||||
import _ctypes_test
|
||||
|
||||
ctype_types = [c_byte, c_ubyte, c_short, c_ushort, c_int, c_uint,
|
||||
c_long, c_ulong, c_longlong, c_ulonglong, c_double, c_float]
|
||||
python_types = [int, int, int, int, int, long,
|
||||
int, long, long, long, float, float]
|
||||
|
||||
class PointersTestCase(unittest.TestCase):
|
||||
|
||||
def test_pointer_crash(self):
|
||||
|
||||
class A(POINTER(c_ulong)):
|
||||
pass
|
||||
|
||||
POINTER(c_ulong)(c_ulong(22))
|
||||
# Pointer can't set contents: has no _type_
|
||||
self.failUnlessRaises(TypeError, A, c_ulong(33))
|
||||
|
||||
def test_pass_pointers(self):
|
||||
dll = CDLL(_ctypes_test.__file__)
|
||||
func = dll._testfunc_p_p
|
||||
func.restype = c_long
|
||||
|
||||
i = c_int(12345678)
|
||||
## func.argtypes = (POINTER(c_int),)
|
||||
address = func(byref(i))
|
||||
self.failUnlessEqual(c_int.from_address(address).value, 12345678)
|
||||
|
||||
func.restype = POINTER(c_int)
|
||||
res = func(pointer(i))
|
||||
self.failUnlessEqual(res.contents.value, 12345678)
|
||||
self.failUnlessEqual(res[0], 12345678)
|
||||
|
||||
def test_change_pointers(self):
|
||||
dll = CDLL(_ctypes_test.__file__)
|
||||
func = dll._testfunc_p_p
|
||||
|
||||
i = c_int(87654)
|
||||
func.restype = POINTER(c_int)
|
||||
func.argtypes = (POINTER(c_int),)
|
||||
|
||||
res = func(pointer(i))
|
||||
self.failUnlessEqual(res[0], 87654)
|
||||
self.failUnlessEqual(res.contents.value, 87654)
|
||||
|
||||
# C code: *res = 54345
|
||||
res[0] = 54345
|
||||
self.failUnlessEqual(i.value, 54345)
|
||||
|
||||
# C code:
|
||||
# int x = 12321;
|
||||
# res = &x
|
||||
res.contents = c_int(12321)
|
||||
self.failUnlessEqual(i.value, 54345)
|
||||
|
||||
def test_callbacks_with_pointers(self):
|
||||
# a function type receiving a pointer
|
||||
PROTOTYPE = CFUNCTYPE(c_int, POINTER(c_int))
|
||||
|
||||
self.result = []
|
||||
|
||||
def func(arg):
|
||||
for i in range(10):
|
||||
## print arg[i],
|
||||
self.result.append(arg[i])
|
||||
## print
|
||||
return 0
|
||||
callback = PROTOTYPE(func)
|
||||
|
||||
dll = CDLL(_ctypes_test.__file__)
|
||||
# This function expects a function pointer,
|
||||
# and calls this with an integer pointer as parameter.
|
||||
# The int pointer points to a table containing the numbers 1..10
|
||||
doit = dll._testfunc_callback_with_pointer
|
||||
|
||||
## i = c_int(42)
|
||||
## callback(byref(i))
|
||||
## self.failUnless(i.value == 84)
|
||||
|
||||
doit(callback)
|
||||
## print self.result
|
||||
doit(callback)
|
||||
## print self.result
|
||||
|
||||
def test_basics(self):
|
||||
from operator import delitem
|
||||
for ct, pt in zip(ctype_types, python_types):
|
||||
i = ct(42)
|
||||
p = pointer(i)
|
||||
## print type(p.contents), ct
|
||||
self.failUnless(type(p.contents) is ct)
|
||||
# p.contents is the same as p[0]
|
||||
## print p.contents
|
||||
## self.failUnless(p.contents == 42)
|
||||
## self.failUnless(p[0] == 42)
|
||||
|
||||
self.assertRaises(TypeError, delitem, p, 0)
|
||||
|
||||
def test_from_address(self):
|
||||
from array import array
|
||||
a = array('i', [100, 200, 300, 400, 500])
|
||||
addr = a.buffer_info()[0]
|
||||
|
||||
p = POINTER(POINTER(c_int))
|
||||
## print dir(p)
|
||||
## print p.from_address
|
||||
## print p.from_address(addr)[0][0]
|
||||
|
||||
def test_other(self):
|
||||
class Table(Structure):
|
||||
_fields_ = [("a", c_int),
|
||||
("b", c_int),
|
||||
("c", c_int)]
|
||||
|
||||
pt = pointer(Table(1, 2, 3))
|
||||
|
||||
self.failUnlessEqual(pt.contents.a, 1)
|
||||
self.failUnlessEqual(pt.contents.b, 2)
|
||||
self.failUnlessEqual(pt.contents.c, 3)
|
||||
|
||||
pt.contents.c = 33
|
||||
|
||||
from ctypes import _pointer_type_cache
|
||||
del _pointer_type_cache[Table]
|
||||
|
||||
def test_basic(self):
|
||||
p = pointer(c_int(42))
|
||||
# Although a pointer can be indexed, it ha no length
|
||||
self.assertRaises(TypeError, len, p)
|
||||
self.failUnlessEqual(p[0], 42)
|
||||
self.failUnlessEqual(p.contents.value, 42)
|
||||
|
||||
def test_charpp(self):
|
||||
"""Test that a character pointer-to-pointer is correctly passed"""
|
||||
dll = CDLL(_ctypes_test.__file__)
|
||||
func = dll._testfunc_c_p_p
|
||||
func.restype = c_char_p
|
||||
argv = (c_char_p * 2)()
|
||||
argc = c_int( 2 )
|
||||
argv[0] = 'hello'
|
||||
argv[1] = 'world'
|
||||
result = func( byref(argc), argv )
|
||||
assert result == 'world', result
|
||||
|
||||
def test_bug_1467852(self):
|
||||
# http://sourceforge.net/tracker/?func=detail&atid=532154&aid=1467852&group_id=71702
|
||||
x = c_int(5)
|
||||
dummy = []
|
||||
for i in range(32000):
|
||||
dummy.append(c_int(i))
|
||||
y = c_int(6)
|
||||
p = pointer(x)
|
||||
pp = pointer(p)
|
||||
q = pointer(y)
|
||||
pp[0] = q # <==
|
||||
self.failUnlessEqual(p[0], 6)
|
||||
def test_c_void_p(self):
|
||||
# http://sourceforge.net/tracker/?func=detail&aid=1518190&group_id=5470&atid=105470
|
||||
if sizeof(c_void_p) == 4:
|
||||
self.failUnlessEqual(c_void_p(0xFFFFFFFFL).value,
|
||||
c_void_p(-1).value)
|
||||
self.failUnlessEqual(c_void_p(0xFFFFFFFFFFFFFFFFL).value,
|
||||
c_void_p(-1).value)
|
||||
elif sizeof(c_void_p) == 8:
|
||||
self.failUnlessEqual(c_void_p(0xFFFFFFFFL).value,
|
||||
0xFFFFFFFFL)
|
||||
self.failUnlessEqual(c_void_p(0xFFFFFFFFFFFFFFFFL).value,
|
||||
c_void_p(-1).value)
|
||||
self.failUnlessEqual(c_void_p(0xFFFFFFFFFFFFFFFFFFFFFFFFL).value,
|
||||
c_void_p(-1).value)
|
||||
|
||||
self.assertRaises(TypeError, c_void_p, 3.14) # make sure floats are NOT accepted
|
||||
self.assertRaises(TypeError, c_void_p, object()) # nor other objects
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -1,203 +0,0 @@
|
|||
from ctypes import *
|
||||
import unittest
|
||||
|
||||
# IMPORTANT INFO:
|
||||
#
|
||||
# Consider this call:
|
||||
# func.restype = c_char_p
|
||||
# func(c_char_p("123"))
|
||||
# It returns
|
||||
# "123"
|
||||
#
|
||||
# WHY IS THIS SO?
|
||||
#
|
||||
# argument tuple (c_char_p("123"), ) is destroyed after the function
|
||||
# func is called, but NOT before the result is actually built.
|
||||
#
|
||||
# If the arglist would be destroyed BEFORE the result has been built,
|
||||
# the c_char_p("123") object would already have a zero refcount,
|
||||
# and the pointer passed to (and returned by) the function would
|
||||
# probably point to deallocated space.
|
||||
#
|
||||
# In this case, there would have to be an additional reference to the argument...
|
||||
|
||||
import _ctypes_test
|
||||
testdll = CDLL(_ctypes_test.__file__)
|
||||
|
||||
# Return machine address `a` as a (possibly long) non-negative integer.
|
||||
# Starting with Python 2.5, id(anything) is always non-negative, and
|
||||
# the ctypes addressof() inherits that via PyLong_FromVoidPtr().
|
||||
def positive_address(a):
|
||||
if a >= 0:
|
||||
return a
|
||||
# View the bits in `a` as unsigned instead.
|
||||
import struct
|
||||
num_bits = struct.calcsize("P") * 8 # num bits in native machine address
|
||||
a += 1L << num_bits
|
||||
assert a >= 0
|
||||
return a
|
||||
|
||||
def c_wbuffer(init):
|
||||
n = len(init) + 1
|
||||
return (c_wchar * n)(*init)
|
||||
|
||||
class CharPointersTestCase(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
func = testdll._testfunc_p_p
|
||||
func.restype = c_long
|
||||
func.argtypes = None
|
||||
|
||||
def test_int_pointer_arg(self):
|
||||
func = testdll._testfunc_p_p
|
||||
func.restype = c_long
|
||||
self.failUnlessEqual(0, func(0))
|
||||
|
||||
ci = c_int(0)
|
||||
|
||||
func.argtypes = POINTER(c_int),
|
||||
self.failUnlessEqual(positive_address(addressof(ci)),
|
||||
positive_address(func(byref(ci))))
|
||||
|
||||
func.argtypes = c_char_p,
|
||||
self.assertRaises(ArgumentError, func, byref(ci))
|
||||
|
||||
func.argtypes = POINTER(c_short),
|
||||
self.assertRaises(ArgumentError, func, byref(ci))
|
||||
|
||||
func.argtypes = POINTER(c_double),
|
||||
self.assertRaises(ArgumentError, func, byref(ci))
|
||||
|
||||
def test_POINTER_c_char_arg(self):
|
||||
func = testdll._testfunc_p_p
|
||||
func.restype = c_char_p
|
||||
func.argtypes = POINTER(c_char),
|
||||
|
||||
self.failUnlessEqual(None, func(None))
|
||||
self.failUnlessEqual("123", func("123"))
|
||||
self.failUnlessEqual(None, func(c_char_p(None)))
|
||||
self.failUnlessEqual("123", func(c_char_p("123")))
|
||||
|
||||
self.failUnlessEqual("123", func(c_buffer("123")))
|
||||
ca = c_char("a")
|
||||
self.failUnlessEqual("a", func(pointer(ca))[0])
|
||||
self.failUnlessEqual("a", func(byref(ca))[0])
|
||||
|
||||
def test_c_char_p_arg(self):
|
||||
func = testdll._testfunc_p_p
|
||||
func.restype = c_char_p
|
||||
func.argtypes = c_char_p,
|
||||
|
||||
self.failUnlessEqual(None, func(None))
|
||||
self.failUnlessEqual("123", func("123"))
|
||||
self.failUnlessEqual(None, func(c_char_p(None)))
|
||||
self.failUnlessEqual("123", func(c_char_p("123")))
|
||||
|
||||
self.failUnlessEqual("123", func(c_buffer("123")))
|
||||
ca = c_char("a")
|
||||
self.failUnlessEqual("a", func(pointer(ca))[0])
|
||||
self.failUnlessEqual("a", func(byref(ca))[0])
|
||||
|
||||
def test_c_void_p_arg(self):
|
||||
func = testdll._testfunc_p_p
|
||||
func.restype = c_char_p
|
||||
func.argtypes = c_void_p,
|
||||
|
||||
self.failUnlessEqual(None, func(None))
|
||||
self.failUnlessEqual("123", func("123"))
|
||||
self.failUnlessEqual("123", func(c_char_p("123")))
|
||||
self.failUnlessEqual(None, func(c_char_p(None)))
|
||||
|
||||
self.failUnlessEqual("123", func(c_buffer("123")))
|
||||
ca = c_char("a")
|
||||
self.failUnlessEqual("a", func(pointer(ca))[0])
|
||||
self.failUnlessEqual("a", func(byref(ca))[0])
|
||||
|
||||
func(byref(c_int()))
|
||||
func(pointer(c_int()))
|
||||
func((c_int * 3)())
|
||||
|
||||
try:
|
||||
func.restype = c_wchar_p
|
||||
except NameError:
|
||||
pass
|
||||
else:
|
||||
self.failUnlessEqual(None, func(c_wchar_p(None)))
|
||||
self.failUnlessEqual(u"123", func(c_wchar_p(u"123")))
|
||||
|
||||
def test_instance(self):
|
||||
func = testdll._testfunc_p_p
|
||||
func.restype = c_void_p
|
||||
|
||||
class X:
|
||||
_as_parameter_ = None
|
||||
|
||||
func.argtypes = c_void_p,
|
||||
self.failUnlessEqual(None, func(X()))
|
||||
|
||||
func.argtypes = None
|
||||
self.failUnlessEqual(None, func(X()))
|
||||
|
||||
try:
|
||||
c_wchar
|
||||
except NameError:
|
||||
pass
|
||||
else:
|
||||
class WCharPointersTestCase(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
func = testdll._testfunc_p_p
|
||||
func.restype = c_int
|
||||
func.argtypes = None
|
||||
|
||||
|
||||
def test_POINTER_c_wchar_arg(self):
|
||||
func = testdll._testfunc_p_p
|
||||
func.restype = c_wchar_p
|
||||
func.argtypes = POINTER(c_wchar),
|
||||
|
||||
self.failUnlessEqual(None, func(None))
|
||||
self.failUnlessEqual(u"123", func(u"123"))
|
||||
self.failUnlessEqual(None, func(c_wchar_p(None)))
|
||||
self.failUnlessEqual(u"123", func(c_wchar_p(u"123")))
|
||||
|
||||
self.failUnlessEqual(u"123", func(c_wbuffer(u"123")))
|
||||
ca = c_wchar("a")
|
||||
self.failUnlessEqual(u"a", func(pointer(ca))[0])
|
||||
self.failUnlessEqual(u"a", func(byref(ca))[0])
|
||||
|
||||
def test_c_wchar_p_arg(self):
|
||||
func = testdll._testfunc_p_p
|
||||
func.restype = c_wchar_p
|
||||
func.argtypes = c_wchar_p,
|
||||
|
||||
c_wchar_p.from_param(u"123")
|
||||
|
||||
self.failUnlessEqual(None, func(None))
|
||||
self.failUnlessEqual("123", func(u"123"))
|
||||
self.failUnlessEqual(None, func(c_wchar_p(None)))
|
||||
self.failUnlessEqual("123", func(c_wchar_p("123")))
|
||||
|
||||
# XXX Currently, these raise TypeErrors, although they shouldn't:
|
||||
self.failUnlessEqual("123", func(c_wbuffer("123")))
|
||||
ca = c_wchar("a")
|
||||
self.failUnlessEqual("a", func(pointer(ca))[0])
|
||||
self.failUnlessEqual("a", func(byref(ca))[0])
|
||||
|
||||
class ArrayTest(unittest.TestCase):
|
||||
def test(self):
|
||||
func = testdll._testfunc_ai8
|
||||
func.restype = POINTER(c_int)
|
||||
func.argtypes = c_int * 8,
|
||||
|
||||
func((c_int * 8)(1, 2, 3, 4, 5, 6, 7, 8))
|
||||
|
||||
# This did crash before:
|
||||
|
||||
def func(): pass
|
||||
CFUNCTYPE(None, c_int * 3)(func)
|
||||
|
||||
################################################################
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -1,87 +0,0 @@
|
|||
from ctypes import *
|
||||
import unittest, sys
|
||||
from ctypes.test import is_resource_enabled
|
||||
|
||||
################################################################
|
||||
# This section should be moved into ctypes\__init__.py, when it's ready.
|
||||
|
||||
from _ctypes import PyObj_FromPtr
|
||||
|
||||
################################################################
|
||||
|
||||
from sys import getrefcount as grc
|
||||
|
||||
|
||||
class PythonAPITestCase(unittest.TestCase):
|
||||
|
||||
def test_PyString_FromStringAndSize(self):
|
||||
PyString_FromStringAndSize = pythonapi.PyString_FromStringAndSize
|
||||
|
||||
PyString_FromStringAndSize.restype = py_object
|
||||
PyString_FromStringAndSize.argtypes = c_char_p, c_int
|
||||
|
||||
self.failUnlessEqual(PyString_FromStringAndSize("abcdefghi", 3), "abc")
|
||||
|
||||
def test_PyString_FromString(self):
|
||||
pythonapi.PyString_FromString.restype = py_object
|
||||
pythonapi.PyString_FromString.argtypes = (c_char_p,)
|
||||
|
||||
s = "abc"
|
||||
refcnt = grc(s)
|
||||
pyob = pythonapi.PyString_FromString(s)
|
||||
self.failUnlessEqual(grc(s), refcnt)
|
||||
self.failUnlessEqual(s, pyob)
|
||||
del pyob
|
||||
self.failUnlessEqual(grc(s), refcnt)
|
||||
|
||||
if is_resource_enabled("refcount"):
|
||||
# This test is unreliable, because it is possible that code in
|
||||
# unittest changes the refcount of the '42' integer. So, it
|
||||
# is disabled by default.
|
||||
def test_PyInt_Long(self):
|
||||
ref42 = grc(42)
|
||||
pythonapi.PyInt_FromLong.restype = py_object
|
||||
self.failUnlessEqual(pythonapi.PyInt_FromLong(42), 42)
|
||||
|
||||
self.failUnlessEqual(grc(42), ref42)
|
||||
|
||||
pythonapi.PyInt_AsLong.argtypes = (py_object,)
|
||||
pythonapi.PyInt_AsLong.restype = c_long
|
||||
|
||||
res = pythonapi.PyInt_AsLong(42)
|
||||
self.failUnlessEqual(grc(res), ref42 + 1)
|
||||
del res
|
||||
self.failUnlessEqual(grc(42), ref42)
|
||||
|
||||
def test_PyObj_FromPtr(self):
|
||||
s = "abc def ghi jkl"
|
||||
ref = grc(s)
|
||||
# id(python-object) is the address
|
||||
pyobj = PyObj_FromPtr(id(s))
|
||||
self.failUnless(s is pyobj)
|
||||
|
||||
self.failUnlessEqual(grc(s), ref + 1)
|
||||
del pyobj
|
||||
self.failUnlessEqual(grc(s), ref)
|
||||
|
||||
def test_PyOS_snprintf(self):
|
||||
PyOS_snprintf = pythonapi.PyOS_snprintf
|
||||
PyOS_snprintf.argtypes = POINTER(c_char), c_int, c_char_p
|
||||
|
||||
buf = c_buffer(256)
|
||||
PyOS_snprintf(buf, sizeof(buf), "Hello from %s", "ctypes")
|
||||
self.failUnlessEqual(buf.value, "Hello from ctypes")
|
||||
|
||||
PyOS_snprintf(buf, sizeof(buf), "Hello from %s", "ctypes", 1, 2, 3)
|
||||
self.failUnlessEqual(buf.value, "Hello from ctypes")
|
||||
|
||||
# not enough arguments
|
||||
self.failUnlessRaises(TypeError, PyOS_snprintf, buf)
|
||||
|
||||
def test_pyobject_repr(self):
|
||||
self.failUnlessEqual(repr(py_object()), "py_object(<NULL>)")
|
||||
self.failUnlessEqual(repr(py_object(42)), "py_object(42)")
|
||||
self.failUnlessEqual(repr(py_object(object)), "py_object(%r)" % object)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
|
@ -1,71 +0,0 @@
|
|||
from ctypes import *
|
||||
import unittest, sys
|
||||
|
||||
def callback_func(arg):
|
||||
42 / arg
|
||||
raise ValueError, arg
|
||||
|
||||
if sys.platform == "win32":
|
||||
|
||||
class call_function_TestCase(unittest.TestCase):
|
||||
# _ctypes.call_function is deprecated and private, but used by
|
||||
# Gary Bishp's readline module. If we have it, we must test it as well.
|
||||
|
||||
def test(self):
|
||||
from _ctypes import call_function
|
||||
hdll = windll.kernel32.LoadLibraryA("kernel32")
|
||||
funcaddr = windll.kernel32.GetProcAddress(hdll, "GetModuleHandleA")
|
||||
|
||||
self.failUnlessEqual(call_function(funcaddr, (None,)),
|
||||
windll.kernel32.GetModuleHandleA(None))
|
||||
|
||||
class CallbackTracbackTestCase(unittest.TestCase):
|
||||
# When an exception is raised in a ctypes callback function, the C
|
||||
# code prints a traceback.
|
||||
#
|
||||
# This test makes sure the exception types *and* the exception
|
||||
# value is printed correctly.
|
||||
#
|
||||
# Changed in 0.9.3: No longer is '(in callback)' prepended to the
|
||||
# error message - instead a additional frame for the C code is
|
||||
# created, then a full traceback printed. When SystemExit is
|
||||
# raised in a callback function, the interpreter exits.
|
||||
|
||||
def capture_stderr(self, func, *args, **kw):
|
||||
# helper - call function 'func', and return the captured stderr
|
||||
import StringIO
|
||||
old_stderr = sys.stderr
|
||||
logger = sys.stderr = StringIO.StringIO()
|
||||
try:
|
||||
func(*args, **kw)
|
||||
finally:
|
||||
sys.stderr = old_stderr
|
||||
return logger.getvalue()
|
||||
|
||||
def test_ValueError(self):
|
||||
cb = CFUNCTYPE(c_int, c_int)(callback_func)
|
||||
out = self.capture_stderr(cb, 42)
|
||||
self.failUnlessEqual(out.splitlines()[-1],
|
||||
"ValueError: 42")
|
||||
|
||||
def test_IntegerDivisionError(self):
|
||||
cb = CFUNCTYPE(c_int, c_int)(callback_func)
|
||||
out = self.capture_stderr(cb, 0)
|
||||
self.failUnlessEqual(out.splitlines()[-1][:19],
|
||||
"ZeroDivisionError: ")
|
||||
|
||||
def test_FloatDivisionError(self):
|
||||
cb = CFUNCTYPE(c_int, c_double)(callback_func)
|
||||
out = self.capture_stderr(cb, 0.0)
|
||||
self.failUnlessEqual(out.splitlines()[-1][:19],
|
||||
"ZeroDivisionError: ")
|
||||
|
||||
def test_TypeErrorDivisionError(self):
|
||||
cb = CFUNCTYPE(c_int, c_char_p)(callback_func)
|
||||
out = self.capture_stderr(cb, "spam")
|
||||
self.failUnlessEqual(out.splitlines()[-1],
|
||||
"TypeError: "
|
||||
"unsupported operand type(s) for /: 'int' and 'str'")
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -1,98 +0,0 @@
|
|||
import unittest
|
||||
import ctypes
|
||||
import gc
|
||||
|
||||
MyCallback = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int)
|
||||
OtherCallback = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_ulonglong)
|
||||
|
||||
import _ctypes_test
|
||||
dll = ctypes.CDLL(_ctypes_test.__file__)
|
||||
|
||||
class RefcountTestCase(unittest.TestCase):
|
||||
|
||||
def test_1(self):
|
||||
from sys import getrefcount as grc
|
||||
|
||||
f = dll._testfunc_callback_i_if
|
||||
f.restype = ctypes.c_int
|
||||
f.argtypes = [ctypes.c_int, MyCallback]
|
||||
|
||||
def callback(value):
|
||||
#print "called back with", value
|
||||
return value
|
||||
|
||||
self.failUnlessEqual(grc(callback), 2)
|
||||
cb = MyCallback(callback)
|
||||
|
||||
self.failUnless(grc(callback) > 2)
|
||||
result = f(-10, cb)
|
||||
self.failUnlessEqual(result, -18)
|
||||
cb = None
|
||||
|
||||
gc.collect()
|
||||
|
||||
self.failUnlessEqual(grc(callback), 2)
|
||||
|
||||
|
||||
def test_refcount(self):
|
||||
from sys import getrefcount as grc
|
||||
def func(*args):
|
||||
pass
|
||||
# this is the standard refcount for func
|
||||
self.failUnlessEqual(grc(func), 2)
|
||||
|
||||
# the CFuncPtr instance holds atr least one refcount on func:
|
||||
f = OtherCallback(func)
|
||||
self.failUnless(grc(func) > 2)
|
||||
|
||||
# and may release it again
|
||||
del f
|
||||
self.failUnless(grc(func) >= 2)
|
||||
|
||||
# but now it must be gone
|
||||
gc.collect()
|
||||
self.failUnless(grc(func) == 2)
|
||||
|
||||
class X(ctypes.Structure):
|
||||
_fields_ = [("a", OtherCallback)]
|
||||
x = X()
|
||||
x.a = OtherCallback(func)
|
||||
|
||||
# the CFuncPtr instance holds atr least one refcount on func:
|
||||
self.failUnless(grc(func) > 2)
|
||||
|
||||
# and may release it again
|
||||
del x
|
||||
self.failUnless(grc(func) >= 2)
|
||||
|
||||
# and now it must be gone again
|
||||
gc.collect()
|
||||
self.failUnlessEqual(grc(func), 2)
|
||||
|
||||
f = OtherCallback(func)
|
||||
|
||||
# the CFuncPtr instance holds atr least one refcount on func:
|
||||
self.failUnless(grc(func) > 2)
|
||||
|
||||
# create a cycle
|
||||
f.cycle = f
|
||||
|
||||
del f
|
||||
gc.collect()
|
||||
self.failUnlessEqual(grc(func), 2)
|
||||
|
||||
class AnotherLeak(unittest.TestCase):
|
||||
def test_callback(self):
|
||||
import sys
|
||||
|
||||
proto = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.c_int)
|
||||
def func(a, b):
|
||||
return a * b * 2
|
||||
f = proto(func)
|
||||
|
||||
a = sys.getrefcount(ctypes.c_int)
|
||||
f(1, 2)
|
||||
self.failUnlessEqual(sys.getrefcount(ctypes.c_int), a)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -1,29 +0,0 @@
|
|||
from ctypes import *
|
||||
import unittest
|
||||
|
||||
subclasses = []
|
||||
for base in [c_byte, c_short, c_int, c_long, c_longlong,
|
||||
c_ubyte, c_ushort, c_uint, c_ulong, c_ulonglong,
|
||||
c_float, c_double]:
|
||||
class X(base):
|
||||
pass
|
||||
subclasses.append(X)
|
||||
|
||||
class X(c_char):
|
||||
pass
|
||||
|
||||
# This test checks if the __repr__ is correct for subclasses of simple types
|
||||
|
||||
class ReprTest(unittest.TestCase):
|
||||
def test_numbers(self):
|
||||
for typ in subclasses:
|
||||
base = typ.__bases__[0]
|
||||
self.failUnless(repr(base(42)).startswith(base.__name__))
|
||||
self.failUnlessEqual("<X object at", repr(typ(42))[:12])
|
||||
|
||||
def test_char(self):
|
||||
self.failUnlessEqual("c_char('x')", repr(c_char('x')))
|
||||
self.failUnlessEqual("<X object at", repr(X('x'))[:12])
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
|
@ -1,35 +0,0 @@
|
|||
import unittest
|
||||
from ctypes import *
|
||||
|
||||
import _ctypes_test
|
||||
|
||||
class ReturnFuncPtrTestCase(unittest.TestCase):
|
||||
|
||||
def test_with_prototype(self):
|
||||
# The _ctypes_test shared lib/dll exports quite some functions for testing.
|
||||
# The get_strchr function returns a *pointer* to the C strchr function.
|
||||
dll = CDLL(_ctypes_test.__file__)
|
||||
get_strchr = dll.get_strchr
|
||||
get_strchr.restype = CFUNCTYPE(c_char_p, c_char_p, c_char)
|
||||
strchr = get_strchr()
|
||||
self.failUnlessEqual(strchr("abcdef", "b"), "bcdef")
|
||||
self.failUnlessEqual(strchr("abcdef", "x"), None)
|
||||
self.assertRaises(ArgumentError, strchr, "abcdef", 3)
|
||||
self.assertRaises(TypeError, strchr, "abcdef")
|
||||
|
||||
def test_without_prototype(self):
|
||||
dll = CDLL(_ctypes_test.__file__)
|
||||
get_strchr = dll.get_strchr
|
||||
# the default 'c_int' would not work on systems where sizeof(int) != sizeof(void *)
|
||||
get_strchr.restype = c_void_p
|
||||
addr = get_strchr()
|
||||
# _CFuncPtr instances are now callable with an integer argument
|
||||
# which denotes a function address:
|
||||
strchr = CFUNCTYPE(c_char_p, c_char_p, c_char)(addr)
|
||||
self.failUnless(strchr("abcdef", "b"), "bcdef")
|
||||
self.failUnlessEqual(strchr("abcdef", "x"), None)
|
||||
self.assertRaises(ArgumentError, strchr, "abcdef", 3)
|
||||
self.assertRaises(TypeError, strchr, "abcdef")
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
|
@ -1,55 +0,0 @@
|
|||
import unittest
|
||||
from ctypes import *
|
||||
|
||||
class MyInt(c_int):
|
||||
def __cmp__(self, other):
|
||||
if type(other) != MyInt:
|
||||
return -1
|
||||
return cmp(self.value, other.value)
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
|
||||
def test_compare(self):
|
||||
self.failUnlessEqual(MyInt(3), MyInt(3))
|
||||
self.failIfEqual(MyInt(42), MyInt(43))
|
||||
|
||||
def test_ignore_retval(self):
|
||||
# Test if the return value of a callback is ignored
|
||||
# if restype is None
|
||||
proto = CFUNCTYPE(None)
|
||||
def func():
|
||||
return (1, "abc", None)
|
||||
|
||||
cb = proto(func)
|
||||
self.failUnlessEqual(None, cb())
|
||||
|
||||
|
||||
def test_int_callback(self):
|
||||
args = []
|
||||
def func(arg):
|
||||
args.append(arg)
|
||||
return arg
|
||||
|
||||
cb = CFUNCTYPE(None, MyInt)(func)
|
||||
|
||||
self.failUnlessEqual(None, cb(42))
|
||||
self.failUnlessEqual(type(args[-1]), MyInt)
|
||||
|
||||
cb = CFUNCTYPE(c_int, c_int)(func)
|
||||
|
||||
self.failUnlessEqual(42, cb(42))
|
||||
self.failUnlessEqual(type(args[-1]), int)
|
||||
|
||||
def test_int_struct(self):
|
||||
class X(Structure):
|
||||
_fields_ = [("x", MyInt)]
|
||||
|
||||
self.failUnlessEqual(X().x, MyInt())
|
||||
|
||||
s = X()
|
||||
s.x = MyInt(42)
|
||||
|
||||
self.failUnlessEqual(s.x, MyInt(42))
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
|
@ -1,27 +0,0 @@
|
|||
# Test specifically-sized containers.
|
||||
|
||||
import unittest
|
||||
from ctypes import *
|
||||
|
||||
class SizesTestCase(unittest.TestCase):
|
||||
def test_8(self):
|
||||
self.failUnlessEqual(1, sizeof(c_int8))
|
||||
self.failUnlessEqual(1, sizeof(c_uint8))
|
||||
|
||||
def test_16(self):
|
||||
self.failUnlessEqual(2, sizeof(c_int16))
|
||||
self.failUnlessEqual(2, sizeof(c_uint16))
|
||||
|
||||
def test_32(self):
|
||||
self.failUnlessEqual(4, sizeof(c_int32))
|
||||
self.failUnlessEqual(4, sizeof(c_uint32))
|
||||
|
||||
def test_64(self):
|
||||
self.failUnlessEqual(8, sizeof(c_int64))
|
||||
self.failUnlessEqual(8, sizeof(c_uint64))
|
||||
|
||||
def test_size_t(self):
|
||||
self.failUnlessEqual(sizeof(c_void_p), sizeof(c_size_t))
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
|
@ -1,120 +0,0 @@
|
|||
import unittest
|
||||
from ctypes import *
|
||||
|
||||
import _ctypes_test
|
||||
|
||||
class SlicesTestCase(unittest.TestCase):
|
||||
def test_getslice_cint(self):
|
||||
a = (c_int * 100)(*xrange(1100, 1200))
|
||||
b = range(1100, 1200)
|
||||
self.failUnlessEqual(a[0:2], b[0:2])
|
||||
self.failUnlessEqual(len(a), len(b))
|
||||
self.failUnlessEqual(a[5:7], b[5:7])
|
||||
self.failUnlessEqual(a[-1], b[-1])
|
||||
self.failUnlessEqual(a[:], b[:])
|
||||
|
||||
a[0:5] = range(5, 10)
|
||||
self.failUnlessEqual(a[0:5], range(5, 10))
|
||||
|
||||
def test_setslice_cint(self):
|
||||
a = (c_int * 100)(*xrange(1100, 1200))
|
||||
b = range(1100, 1200)
|
||||
|
||||
a[32:47] = range(32, 47)
|
||||
self.failUnlessEqual(a[32:47], range(32, 47))
|
||||
|
||||
from operator import setslice
|
||||
|
||||
# TypeError: int expected instead of str instance
|
||||
self.assertRaises(TypeError, setslice, a, 0, 5, "abcde")
|
||||
# TypeError: int expected instead of str instance
|
||||
self.assertRaises(TypeError, setslice, a, 0, 5, ["a", "b", "c", "d", "e"])
|
||||
# TypeError: int expected instead of float instance
|
||||
self.assertRaises(TypeError, setslice, a, 0, 5, [1, 2, 3, 4, 3.14])
|
||||
# ValueError: Can only assign sequence of same size
|
||||
self.assertRaises(ValueError, setslice, a, 0, 5, range(32))
|
||||
|
||||
def test_char_ptr(self):
|
||||
s = "abcdefghijklmnopqrstuvwxyz"
|
||||
|
||||
dll = CDLL(_ctypes_test.__file__)
|
||||
dll.my_strdup.restype = POINTER(c_char)
|
||||
dll.my_free.restype = None
|
||||
res = dll.my_strdup(s)
|
||||
self.failUnlessEqual(res[:len(s)], s)
|
||||
|
||||
import operator
|
||||
self.assertRaises(TypeError, operator.setslice,
|
||||
res, 0, 5, u"abcde")
|
||||
dll.my_free(res)
|
||||
|
||||
dll.my_strdup.restype = POINTER(c_byte)
|
||||
res = dll.my_strdup(s)
|
||||
self.failUnlessEqual(res[:len(s)], range(ord("a"), ord("z")+1))
|
||||
dll.my_free(res)
|
||||
|
||||
def test_char_ptr_with_free(self):
|
||||
dll = CDLL(_ctypes_test.__file__)
|
||||
s = "abcdefghijklmnopqrstuvwxyz"
|
||||
|
||||
class allocated_c_char_p(c_char_p):
|
||||
pass
|
||||
|
||||
dll.my_free.restype = None
|
||||
def errcheck(result, func, args):
|
||||
retval = result.value
|
||||
dll.my_free(result)
|
||||
return retval
|
||||
|
||||
dll.my_strdup.restype = allocated_c_char_p
|
||||
dll.my_strdup.errcheck = errcheck
|
||||
try:
|
||||
res = dll.my_strdup(s)
|
||||
self.failUnlessEqual(res, s)
|
||||
finally:
|
||||
del dll.my_strdup.errcheck
|
||||
|
||||
|
||||
def test_char_array(self):
|
||||
s = "abcdefghijklmnopqrstuvwxyz\0"
|
||||
|
||||
p = (c_char * 27)(*s)
|
||||
self.failUnlessEqual(p[:], s)
|
||||
|
||||
|
||||
try:
|
||||
c_wchar
|
||||
except NameError:
|
||||
pass
|
||||
else:
|
||||
def test_wchar_ptr(self):
|
||||
s = u"abcdefghijklmnopqrstuvwxyz\0"
|
||||
|
||||
dll = CDLL(_ctypes_test.__file__)
|
||||
dll.my_wcsdup.restype = POINTER(c_wchar)
|
||||
dll.my_wcsdup.argtypes = POINTER(c_wchar),
|
||||
dll.my_free.restype = None
|
||||
res = dll.my_wcsdup(s)
|
||||
self.failUnlessEqual(res[:len(s)], s)
|
||||
|
||||
import operator
|
||||
self.assertRaises(TypeError, operator.setslice,
|
||||
res, 0, 5, u"abcde")
|
||||
dll.my_free(res)
|
||||
|
||||
if sizeof(c_wchar) == sizeof(c_short):
|
||||
dll.my_wcsdup.restype = POINTER(c_short)
|
||||
elif sizeof(c_wchar) == sizeof(c_int):
|
||||
dll.my_wcsdup.restype = POINTER(c_int)
|
||||
elif sizeof(c_wchar) == sizeof(c_long):
|
||||
dll.my_wcsdup.restype = POINTER(c_long)
|
||||
else:
|
||||
return
|
||||
res = dll.my_wcsdup(s)
|
||||
self.failUnlessEqual(res[:len(s)-1], range(ord("a"), ord("z")+1))
|
||||
dll.my_free(res)
|
||||
|
||||
################################################################
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
|
@ -1,75 +0,0 @@
|
|||
import unittest
|
||||
from ctypes import *
|
||||
|
||||
import _ctypes_test
|
||||
|
||||
lib = CDLL(_ctypes_test.__file__)
|
||||
|
||||
class StringPtrTestCase(unittest.TestCase):
|
||||
|
||||
def test__POINTER_c_char(self):
|
||||
class X(Structure):
|
||||
_fields_ = [("str", POINTER(c_char))]
|
||||
x = X()
|
||||
|
||||
# NULL pointer access
|
||||
self.assertRaises(ValueError, getattr, x.str, "contents")
|
||||
b = c_buffer("Hello, World")
|
||||
from sys import getrefcount as grc
|
||||
self.failUnlessEqual(grc(b), 2)
|
||||
x.str = b
|
||||
self.failUnlessEqual(grc(b), 3)
|
||||
|
||||
# POINTER(c_char) and Python string is NOT compatible
|
||||
# POINTER(c_char) and c_buffer() is compatible
|
||||
for i in range(len(b)):
|
||||
self.failUnlessEqual(b[i], x.str[i])
|
||||
|
||||
self.assertRaises(TypeError, setattr, x, "str", "Hello, World")
|
||||
|
||||
def test__c_char_p(self):
|
||||
class X(Structure):
|
||||
_fields_ = [("str", c_char_p)]
|
||||
x = X()
|
||||
|
||||
# c_char_p and Python string is compatible
|
||||
# c_char_p and c_buffer is NOT compatible
|
||||
self.failUnlessEqual(x.str, None)
|
||||
x.str = "Hello, World"
|
||||
self.failUnlessEqual(x.str, "Hello, World")
|
||||
b = c_buffer("Hello, World")
|
||||
self.failUnlessRaises(TypeError, setattr, x, "str", b)
|
||||
|
||||
|
||||
def test_functions(self):
|
||||
strchr = lib.my_strchr
|
||||
strchr.restype = c_char_p
|
||||
|
||||
# c_char_p and Python string is compatible
|
||||
# c_char_p and c_buffer are now compatible
|
||||
strchr.argtypes = c_char_p, c_char
|
||||
self.failUnlessEqual(strchr("abcdef", "c"), "cdef")
|
||||
self.failUnlessEqual(strchr(c_buffer("abcdef"), "c"), "cdef")
|
||||
|
||||
# POINTER(c_char) and Python string is NOT compatible
|
||||
# POINTER(c_char) and c_buffer() is compatible
|
||||
strchr.argtypes = POINTER(c_char), c_char
|
||||
buf = c_buffer("abcdef")
|
||||
self.failUnlessEqual(strchr(buf, "c"), "cdef")
|
||||
self.failUnlessEqual(strchr("abcdef", "c"), "cdef")
|
||||
|
||||
# XXX These calls are dangerous, because the first argument
|
||||
# to strchr is no longer valid after the function returns!
|
||||
# So we must keep a reference to buf separately
|
||||
|
||||
strchr.restype = POINTER(c_char)
|
||||
buf = c_buffer("abcdef")
|
||||
r = strchr(buf, "c")
|
||||
x = r[0], r[1], r[2], r[3], r[4]
|
||||
self.failUnlessEqual(x, ("c", "d", "e", "f", "\000"))
|
||||
del buf
|
||||
# x1 will NOT be the same as x, usually:
|
||||
x1 = r[0], r[1], r[2], r[3], r[4]
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -1,215 +0,0 @@
|
|||
import unittest
|
||||
from ctypes import *
|
||||
|
||||
class StringArrayTestCase(unittest.TestCase):
|
||||
def test(self):
|
||||
BUF = c_char * 4
|
||||
|
||||
buf = BUF("a", "b", "c")
|
||||
self.failUnlessEqual(buf.value, "abc")
|
||||
self.failUnlessEqual(buf.raw, "abc\000")
|
||||
|
||||
buf.value = "ABCD"
|
||||
self.failUnlessEqual(buf.value, "ABCD")
|
||||
self.failUnlessEqual(buf.raw, "ABCD")
|
||||
|
||||
buf.value = "x"
|
||||
self.failUnlessEqual(buf.value, "x")
|
||||
self.failUnlessEqual(buf.raw, "x\000CD")
|
||||
|
||||
buf[1] = "Z"
|
||||
self.failUnlessEqual(buf.value, "xZCD")
|
||||
self.failUnlessEqual(buf.raw, "xZCD")
|
||||
|
||||
self.assertRaises(ValueError, setattr, buf, "value", "aaaaaaaa")
|
||||
self.assertRaises(TypeError, setattr, buf, "value", 42)
|
||||
|
||||
def test_c_buffer_value(self):
|
||||
buf = c_buffer(32)
|
||||
|
||||
buf.value = "Hello, World"
|
||||
self.failUnlessEqual(buf.value, "Hello, World")
|
||||
|
||||
self.failUnlessRaises(TypeError, setattr, buf, "value", buffer("Hello, World"))
|
||||
self.assertRaises(TypeError, setattr, buf, "value", buffer("abc"))
|
||||
self.assertRaises(ValueError, setattr, buf, "raw", buffer("x" * 100))
|
||||
|
||||
def test_c_buffer_raw(self):
|
||||
buf = c_buffer(32)
|
||||
|
||||
buf.raw = buffer("Hello, World")
|
||||
self.failUnlessEqual(buf.value, "Hello, World")
|
||||
self.assertRaises(TypeError, setattr, buf, "value", buffer("abc"))
|
||||
self.assertRaises(ValueError, setattr, buf, "raw", buffer("x" * 100))
|
||||
|
||||
def test_param_1(self):
|
||||
BUF = c_char * 4
|
||||
buf = BUF()
|
||||
## print c_char_p.from_param(buf)
|
||||
|
||||
def test_param_2(self):
|
||||
BUF = c_char * 4
|
||||
buf = BUF()
|
||||
## print BUF.from_param(c_char_p("python"))
|
||||
## print BUF.from_param(BUF(*"pyth"))
|
||||
|
||||
try:
|
||||
c_wchar
|
||||
except NameError:
|
||||
pass
|
||||
else:
|
||||
class WStringArrayTestCase(unittest.TestCase):
|
||||
def test(self):
|
||||
BUF = c_wchar * 4
|
||||
|
||||
buf = BUF(u"a", u"b", u"c")
|
||||
self.failUnlessEqual(buf.value, u"abc")
|
||||
|
||||
buf.value = u"ABCD"
|
||||
self.failUnlessEqual(buf.value, u"ABCD")
|
||||
|
||||
buf.value = u"x"
|
||||
self.failUnlessEqual(buf.value, u"x")
|
||||
|
||||
buf[1] = u"Z"
|
||||
self.failUnlessEqual(buf.value, u"xZCD")
|
||||
|
||||
class StringTestCase(unittest.TestCase):
|
||||
def XX_test_basic_strings(self):
|
||||
cs = c_string("abcdef")
|
||||
|
||||
# Cannot call len on a c_string any longer
|
||||
self.assertRaises(TypeError, len, cs)
|
||||
self.failUnlessEqual(sizeof(cs), 7)
|
||||
|
||||
# The value property is the string up to the first terminating NUL.
|
||||
self.failUnlessEqual(cs.value, "abcdef")
|
||||
self.failUnlessEqual(c_string("abc\000def").value, "abc")
|
||||
|
||||
# The raw property is the total buffer contents:
|
||||
self.failUnlessEqual(cs.raw, "abcdef\000")
|
||||
self.failUnlessEqual(c_string("abc\000def").raw, "abc\000def\000")
|
||||
|
||||
# We can change the value:
|
||||
cs.value = "ab"
|
||||
self.failUnlessEqual(cs.value, "ab")
|
||||
self.failUnlessEqual(cs.raw, "ab\000\000\000\000\000")
|
||||
|
||||
cs.raw = "XY"
|
||||
self.failUnlessEqual(cs.value, "XY")
|
||||
self.failUnlessEqual(cs.raw, "XY\000\000\000\000\000")
|
||||
|
||||
self.assertRaises(TypeError, c_string, u"123")
|
||||
|
||||
def XX_test_sized_strings(self):
|
||||
|
||||
# New in releases later than 0.4.0:
|
||||
self.assertRaises(TypeError, c_string, None)
|
||||
|
||||
# New in releases later than 0.4.0:
|
||||
# c_string(number) returns an empty string of size number
|
||||
self.failUnless(len(c_string(32).raw) == 32)
|
||||
self.assertRaises(ValueError, c_string, -1)
|
||||
self.assertRaises(ValueError, c_string, 0)
|
||||
|
||||
# These tests fail, because it is no longer initialized
|
||||
## self.failUnless(c_string(2).value == "")
|
||||
## self.failUnless(c_string(2).raw == "\000\000")
|
||||
self.failUnless(c_string(2).raw[-1] == "\000")
|
||||
self.failUnless(len(c_string(2).raw) == 2)
|
||||
|
||||
def XX_test_initialized_strings(self):
|
||||
|
||||
self.failUnless(c_string("ab", 4).raw[:2] == "ab")
|
||||
self.failUnless(c_string("ab", 4).raw[-1] == "\000")
|
||||
self.failUnless(c_string("ab", 2).raw == "a\000")
|
||||
|
||||
def XX_test_toolong(self):
|
||||
cs = c_string("abcdef")
|
||||
# Much too long string:
|
||||
self.assertRaises(ValueError, setattr, cs, "value", "123456789012345")
|
||||
|
||||
# One char too long values:
|
||||
self.assertRaises(ValueError, setattr, cs, "value", "1234567")
|
||||
|
||||
## def test_perf(self):
|
||||
## check_perf()
|
||||
|
||||
try:
|
||||
c_wchar
|
||||
except NameError:
|
||||
pass
|
||||
else:
|
||||
class WStringTestCase(unittest.TestCase):
|
||||
def test_wchar(self):
|
||||
c_wchar(u"x")
|
||||
repr(byref(c_wchar(u"x")))
|
||||
c_wchar("x")
|
||||
|
||||
|
||||
def X_test_basic_wstrings(self):
|
||||
cs = c_wstring(u"abcdef")
|
||||
|
||||
# XXX This behaviour is about to change:
|
||||
# len returns the size of the internal buffer in bytes.
|
||||
# This includes the terminating NUL character.
|
||||
self.failUnless(sizeof(cs) == 14)
|
||||
|
||||
# The value property is the string up to the first terminating NUL.
|
||||
self.failUnless(cs.value == u"abcdef")
|
||||
self.failUnless(c_wstring(u"abc\000def").value == u"abc")
|
||||
|
||||
self.failUnless(c_wstring(u"abc\000def").value == u"abc")
|
||||
|
||||
# The raw property is the total buffer contents:
|
||||
self.failUnless(cs.raw == u"abcdef\000")
|
||||
self.failUnless(c_wstring(u"abc\000def").raw == u"abc\000def\000")
|
||||
|
||||
# We can change the value:
|
||||
cs.value = u"ab"
|
||||
self.failUnless(cs.value == u"ab")
|
||||
self.failUnless(cs.raw == u"ab\000\000\000\000\000")
|
||||
|
||||
self.assertRaises(TypeError, c_wstring, "123")
|
||||
self.assertRaises(ValueError, c_wstring, 0)
|
||||
|
||||
def X_test_toolong(self):
|
||||
cs = c_wstring(u"abcdef")
|
||||
# Much too long string:
|
||||
self.assertRaises(ValueError, setattr, cs, "value", u"123456789012345")
|
||||
|
||||
# One char too long values:
|
||||
self.assertRaises(ValueError, setattr, cs, "value", u"1234567")
|
||||
|
||||
|
||||
def run_test(rep, msg, func, arg):
|
||||
items = range(rep)
|
||||
from time import clock
|
||||
start = clock()
|
||||
for i in items:
|
||||
func(arg); func(arg); func(arg); func(arg); func(arg)
|
||||
stop = clock()
|
||||
print "%20s: %.2f us" % (msg, ((stop-start)*1e6/5/rep))
|
||||
|
||||
def check_perf():
|
||||
# Construct 5 objects
|
||||
|
||||
REP = 200000
|
||||
|
||||
run_test(REP, "c_string(None)", c_string, None)
|
||||
run_test(REP, "c_string('abc')", c_string, 'abc')
|
||||
|
||||
# Python 2.3 -OO, win2k, P4 700 MHz:
|
||||
#
|
||||
# c_string(None): 1.75 us
|
||||
# c_string('abc'): 2.74 us
|
||||
|
||||
# Python 2.2 -OO, win2k, P4 700 MHz:
|
||||
#
|
||||
# c_string(None): 2.95 us
|
||||
# c_string('abc'): 3.67 us
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
## check_perf()
|
||||
unittest.main()
|
|
@ -1,50 +0,0 @@
|
|||
import unittest
|
||||
from ctypes import *
|
||||
|
||||
class StructFieldsTestCase(unittest.TestCase):
|
||||
# Structure/Union classes must get 'finalized' sooner or
|
||||
# later, when one of these things happen:
|
||||
#
|
||||
# 1. _fields_ is set.
|
||||
# 2. An instance is created.
|
||||
# 3. The type is used as field of another Structure/Union.
|
||||
# 4. The type is subclassed
|
||||
#
|
||||
# When they are finalized, assigning _fields_ is no longer allowed.
|
||||
|
||||
def test_1_A(self):
|
||||
class X(Structure):
|
||||
pass
|
||||
self.failUnlessEqual(sizeof(X), 0) # not finalized
|
||||
X._fields_ = [] # finalized
|
||||
self.assertRaises(AttributeError, setattr, X, "_fields_", [])
|
||||
|
||||
def test_1_B(self):
|
||||
class X(Structure):
|
||||
_fields_ = [] # finalized
|
||||
self.assertRaises(AttributeError, setattr, X, "_fields_", [])
|
||||
|
||||
def test_2(self):
|
||||
class X(Structure):
|
||||
pass
|
||||
X()
|
||||
self.assertRaises(AttributeError, setattr, X, "_fields_", [])
|
||||
|
||||
def test_3(self):
|
||||
class X(Structure):
|
||||
pass
|
||||
class Y(Structure):
|
||||
_fields_ = [("x", X)] # finalizes X
|
||||
self.assertRaises(AttributeError, setattr, X, "_fields_", [])
|
||||
|
||||
def test_4(self):
|
||||
class X(Structure):
|
||||
pass
|
||||
class Y(X):
|
||||
pass
|
||||
self.assertRaises(AttributeError, setattr, X, "_fields_", [])
|
||||
Y._fields_ = []
|
||||
self.assertRaises(AttributeError, setattr, X, "_fields_", [])
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
|
@ -1,415 +0,0 @@
|
|||
import unittest
|
||||
from ctypes import *
|
||||
from struct import calcsize
|
||||
|
||||
class SubclassesTest(unittest.TestCase):
|
||||
def test_subclass(self):
|
||||
class X(Structure):
|
||||
_fields_ = [("a", c_int)]
|
||||
|
||||
class Y(X):
|
||||
_fields_ = [("b", c_int)]
|
||||
|
||||
class Z(X):
|
||||
pass
|
||||
|
||||
self.failUnlessEqual(sizeof(X), sizeof(c_int))
|
||||
self.failUnlessEqual(sizeof(Y), sizeof(c_int)*2)
|
||||
self.failUnlessEqual(sizeof(Z), sizeof(c_int))
|
||||
self.failUnlessEqual(X._fields_, [("a", c_int)])
|
||||
self.failUnlessEqual(Y._fields_, [("b", c_int)])
|
||||
self.failUnlessEqual(Z._fields_, [("a", c_int)])
|
||||
|
||||
def test_subclass_delayed(self):
|
||||
class X(Structure):
|
||||
pass
|
||||
self.failUnlessEqual(sizeof(X), 0)
|
||||
X._fields_ = [("a", c_int)]
|
||||
|
||||
class Y(X):
|
||||
pass
|
||||
self.failUnlessEqual(sizeof(Y), sizeof(X))
|
||||
Y._fields_ = [("b", c_int)]
|
||||
|
||||
class Z(X):
|
||||
pass
|
||||
|
||||
self.failUnlessEqual(sizeof(X), sizeof(c_int))
|
||||
self.failUnlessEqual(sizeof(Y), sizeof(c_int)*2)
|
||||
self.failUnlessEqual(sizeof(Z), sizeof(c_int))
|
||||
self.failUnlessEqual(X._fields_, [("a", c_int)])
|
||||
self.failUnlessEqual(Y._fields_, [("b", c_int)])
|
||||
self.failUnlessEqual(Z._fields_, [("a", c_int)])
|
||||
|
||||
class StructureTestCase(unittest.TestCase):
|
||||
formats = {"c": c_char,
|
||||
"b": c_byte,
|
||||
"B": c_ubyte,
|
||||
"h": c_short,
|
||||
"H": c_ushort,
|
||||
"i": c_int,
|
||||
"I": c_uint,
|
||||
"l": c_long,
|
||||
"L": c_ulong,
|
||||
"q": c_longlong,
|
||||
"Q": c_ulonglong,
|
||||
"f": c_float,
|
||||
"d": c_double,
|
||||
}
|
||||
|
||||
def test_simple_structs(self):
|
||||
for code, tp in self.formats.items():
|
||||
class X(Structure):
|
||||
_fields_ = [("x", c_char),
|
||||
("y", tp)]
|
||||
self.failUnlessEqual((sizeof(X), code),
|
||||
(calcsize("c%c0%c" % (code, code)), code))
|
||||
|
||||
def test_unions(self):
|
||||
for code, tp in self.formats.items():
|
||||
class X(Union):
|
||||
_fields_ = [("x", c_char),
|
||||
("y", tp)]
|
||||
self.failUnlessEqual((sizeof(X), code),
|
||||
(calcsize("%c" % (code)), code))
|
||||
|
||||
def test_struct_alignment(self):
|
||||
class X(Structure):
|
||||
_fields_ = [("x", c_char * 3)]
|
||||
self.failUnlessEqual(alignment(X), calcsize("s"))
|
||||
self.failUnlessEqual(sizeof(X), calcsize("3s"))
|
||||
|
||||
class Y(Structure):
|
||||
_fields_ = [("x", c_char * 3),
|
||||
("y", c_int)]
|
||||
self.failUnlessEqual(alignment(Y), calcsize("i"))
|
||||
self.failUnlessEqual(sizeof(Y), calcsize("3si"))
|
||||
|
||||
class SI(Structure):
|
||||
_fields_ = [("a", X),
|
||||
("b", Y)]
|
||||
self.failUnlessEqual(alignment(SI), max(alignment(Y), alignment(X)))
|
||||
self.failUnlessEqual(sizeof(SI), calcsize("3s0i 3si 0i"))
|
||||
|
||||
class IS(Structure):
|
||||
_fields_ = [("b", Y),
|
||||
("a", X)]
|
||||
|
||||
self.failUnlessEqual(alignment(SI), max(alignment(X), alignment(Y)))
|
||||
self.failUnlessEqual(sizeof(IS), calcsize("3si 3s 0i"))
|
||||
|
||||
class XX(Structure):
|
||||
_fields_ = [("a", X),
|
||||
("b", X)]
|
||||
self.failUnlessEqual(alignment(XX), alignment(X))
|
||||
self.failUnlessEqual(sizeof(XX), calcsize("3s 3s 0s"))
|
||||
|
||||
def test_emtpy(self):
|
||||
# I had problems with these
|
||||
#
|
||||
# Although these are patological cases: Empty Structures!
|
||||
class X(Structure):
|
||||
_fields_ = []
|
||||
|
||||
class Y(Union):
|
||||
_fields_ = []
|
||||
|
||||
# Is this really the correct alignment, or should it be 0?
|
||||
self.failUnless(alignment(X) == alignment(Y) == 1)
|
||||
self.failUnless(sizeof(X) == sizeof(Y) == 0)
|
||||
|
||||
class XX(Structure):
|
||||
_fields_ = [("a", X),
|
||||
("b", X)]
|
||||
|
||||
self.failUnlessEqual(alignment(XX), 1)
|
||||
self.failUnlessEqual(sizeof(XX), 0)
|
||||
|
||||
def test_fields(self):
|
||||
# test the offset and size attributes of Structure/Unoin fields.
|
||||
class X(Structure):
|
||||
_fields_ = [("x", c_int),
|
||||
("y", c_char)]
|
||||
|
||||
self.failUnlessEqual(X.x.offset, 0)
|
||||
self.failUnlessEqual(X.x.size, sizeof(c_int))
|
||||
|
||||
self.failUnlessEqual(X.y.offset, sizeof(c_int))
|
||||
self.failUnlessEqual(X.y.size, sizeof(c_char))
|
||||
|
||||
# readonly
|
||||
self.assertRaises((TypeError, AttributeError), setattr, X.x, "offset", 92)
|
||||
self.assertRaises((TypeError, AttributeError), setattr, X.x, "size", 92)
|
||||
|
||||
class X(Union):
|
||||
_fields_ = [("x", c_int),
|
||||
("y", c_char)]
|
||||
|
||||
self.failUnlessEqual(X.x.offset, 0)
|
||||
self.failUnlessEqual(X.x.size, sizeof(c_int))
|
||||
|
||||
self.failUnlessEqual(X.y.offset, 0)
|
||||
self.failUnlessEqual(X.y.size, sizeof(c_char))
|
||||
|
||||
# readonly
|
||||
self.assertRaises((TypeError, AttributeError), setattr, X.x, "offset", 92)
|
||||
self.assertRaises((TypeError, AttributeError), setattr, X.x, "size", 92)
|
||||
|
||||
# XXX Should we check nested data types also?
|
||||
# offset is always relative to the class...
|
||||
|
||||
def test_packed(self):
|
||||
class X(Structure):
|
||||
_fields_ = [("a", c_byte),
|
||||
("b", c_longlong)]
|
||||
_pack_ = 1
|
||||
|
||||
self.failUnlessEqual(sizeof(X), 9)
|
||||
self.failUnlessEqual(X.b.offset, 1)
|
||||
|
||||
class X(Structure):
|
||||
_fields_ = [("a", c_byte),
|
||||
("b", c_longlong)]
|
||||
_pack_ = 2
|
||||
self.failUnlessEqual(sizeof(X), 10)
|
||||
self.failUnlessEqual(X.b.offset, 2)
|
||||
|
||||
class X(Structure):
|
||||
_fields_ = [("a", c_byte),
|
||||
("b", c_longlong)]
|
||||
_pack_ = 4
|
||||
self.failUnlessEqual(sizeof(X), 12)
|
||||
self.failUnlessEqual(X.b.offset, 4)
|
||||
|
||||
import struct
|
||||
longlong_size = struct.calcsize("q")
|
||||
longlong_align = struct.calcsize("bq") - longlong_size
|
||||
|
||||
class X(Structure):
|
||||
_fields_ = [("a", c_byte),
|
||||
("b", c_longlong)]
|
||||
_pack_ = 8
|
||||
|
||||
self.failUnlessEqual(sizeof(X), longlong_align + longlong_size)
|
||||
self.failUnlessEqual(X.b.offset, min(8, longlong_align))
|
||||
|
||||
|
||||
d = {"_fields_": [("a", "b"),
|
||||
("b", "q")],
|
||||
"_pack_": -1}
|
||||
self.assertRaises(ValueError, type(Structure), "X", (Structure,), d)
|
||||
|
||||
def test_initializers(self):
|
||||
class Person(Structure):
|
||||
_fields_ = [("name", c_char*6),
|
||||
("age", c_int)]
|
||||
|
||||
self.assertRaises(TypeError, Person, 42)
|
||||
self.assertRaises(ValueError, Person, "asldkjaslkdjaslkdj")
|
||||
self.assertRaises(TypeError, Person, "Name", "HI")
|
||||
|
||||
# short enough
|
||||
self.failUnlessEqual(Person("12345", 5).name, "12345")
|
||||
# exact fit
|
||||
self.failUnlessEqual(Person("123456", 5).name, "123456")
|
||||
# too long
|
||||
self.assertRaises(ValueError, Person, "1234567", 5)
|
||||
|
||||
|
||||
def test_keyword_initializers(self):
|
||||
class POINT(Structure):
|
||||
_fields_ = [("x", c_int), ("y", c_int)]
|
||||
pt = POINT(1, 2)
|
||||
self.failUnlessEqual((pt.x, pt.y), (1, 2))
|
||||
|
||||
pt = POINT(y=2, x=1)
|
||||
self.failUnlessEqual((pt.x, pt.y), (1, 2))
|
||||
|
||||
def test_invalid_field_types(self):
|
||||
class POINT(Structure):
|
||||
pass
|
||||
self.assertRaises(TypeError, setattr, POINT, "_fields_", [("x", 1), ("y", 2)])
|
||||
|
||||
def test_intarray_fields(self):
|
||||
class SomeInts(Structure):
|
||||
_fields_ = [("a", c_int * 4)]
|
||||
|
||||
# can use tuple to initialize array (but not list!)
|
||||
self.failUnlessEqual(SomeInts((1, 2)).a[:], [1, 2, 0, 0])
|
||||
self.failUnlessEqual(SomeInts((1, 2, 3, 4)).a[:], [1, 2, 3, 4])
|
||||
# too long
|
||||
# XXX Should raise ValueError?, not RuntimeError
|
||||
self.assertRaises(RuntimeError, SomeInts, (1, 2, 3, 4, 5))
|
||||
|
||||
def test_nested_initializers(self):
|
||||
# test initializing nested structures
|
||||
class Phone(Structure):
|
||||
_fields_ = [("areacode", c_char*6),
|
||||
("number", c_char*12)]
|
||||
|
||||
class Person(Structure):
|
||||
_fields_ = [("name", c_char * 12),
|
||||
("phone", Phone),
|
||||
("age", c_int)]
|
||||
|
||||
p = Person("Someone", ("1234", "5678"), 5)
|
||||
|
||||
self.failUnlessEqual(p.name, "Someone")
|
||||
self.failUnlessEqual(p.phone.areacode, "1234")
|
||||
self.failUnlessEqual(p.phone.number, "5678")
|
||||
self.failUnlessEqual(p.age, 5)
|
||||
|
||||
def test_structures_with_wchar(self):
|
||||
try:
|
||||
c_wchar
|
||||
except NameError:
|
||||
return # no unicode
|
||||
|
||||
class PersonW(Structure):
|
||||
_fields_ = [("name", c_wchar * 12),
|
||||
("age", c_int)]
|
||||
|
||||
p = PersonW(u"Someone")
|
||||
self.failUnlessEqual(p.name, "Someone")
|
||||
|
||||
self.failUnlessEqual(PersonW(u"1234567890").name, u"1234567890")
|
||||
self.failUnlessEqual(PersonW(u"12345678901").name, u"12345678901")
|
||||
# exact fit
|
||||
self.failUnlessEqual(PersonW(u"123456789012").name, u"123456789012")
|
||||
#too long
|
||||
self.assertRaises(ValueError, PersonW, u"1234567890123")
|
||||
|
||||
def test_init_errors(self):
|
||||
class Phone(Structure):
|
||||
_fields_ = [("areacode", c_char*6),
|
||||
("number", c_char*12)]
|
||||
|
||||
class Person(Structure):
|
||||
_fields_ = [("name", c_char * 12),
|
||||
("phone", Phone),
|
||||
("age", c_int)]
|
||||
|
||||
cls, msg = self.get_except(Person, "Someone", (1, 2))
|
||||
self.failUnlessEqual(cls, RuntimeError)
|
||||
# In Python 2.5, Exception is a new-style class, and the repr changed
|
||||
if issubclass(Exception, object):
|
||||
self.failUnlessEqual(msg,
|
||||
"(Phone) <type 'exceptions.TypeError'>: "
|
||||
"expected string or Unicode object, int found")
|
||||
else:
|
||||
self.failUnlessEqual(msg,
|
||||
"(Phone) exceptions.TypeError: "
|
||||
"expected string or Unicode object, int found")
|
||||
|
||||
cls, msg = self.get_except(Person, "Someone", ("a", "b", "c"))
|
||||
self.failUnlessEqual(cls, RuntimeError)
|
||||
if issubclass(Exception, object):
|
||||
self.failUnlessEqual(msg,
|
||||
"(Phone) <type 'exceptions.ValueError'>: too many initializers")
|
||||
else:
|
||||
self.failUnlessEqual(msg, "(Phone) exceptions.ValueError: too many initializers")
|
||||
|
||||
|
||||
def get_except(self, func, *args):
|
||||
try:
|
||||
func(*args)
|
||||
except Exception, detail:
|
||||
return detail.__class__, str(detail)
|
||||
|
||||
|
||||
## def test_subclass_creation(self):
|
||||
## meta = type(Structure)
|
||||
## # same as 'class X(Structure): pass'
|
||||
## # fails, since we need either a _fields_ or a _abstract_ attribute
|
||||
## cls, msg = self.get_except(meta, "X", (Structure,), {})
|
||||
## self.failUnlessEqual((cls, msg),
|
||||
## (AttributeError, "class must define a '_fields_' attribute"))
|
||||
|
||||
def test_abstract_class(self):
|
||||
class X(Structure):
|
||||
_abstract_ = "something"
|
||||
# try 'X()'
|
||||
cls, msg = self.get_except(eval, "X()", locals())
|
||||
self.failUnlessEqual((cls, msg), (TypeError, "abstract class"))
|
||||
|
||||
def test_methods(self):
|
||||
## class X(Structure):
|
||||
## _fields_ = []
|
||||
|
||||
self.failUnless("in_dll" in dir(type(Structure)))
|
||||
self.failUnless("from_address" in dir(type(Structure)))
|
||||
self.failUnless("in_dll" in dir(type(Structure)))
|
||||
|
||||
class PointerMemberTestCase(unittest.TestCase):
|
||||
|
||||
def test(self):
|
||||
# a Structure with a POINTER field
|
||||
class S(Structure):
|
||||
_fields_ = [("array", POINTER(c_int))]
|
||||
|
||||
s = S()
|
||||
# We can assign arrays of the correct type
|
||||
s.array = (c_int * 3)(1, 2, 3)
|
||||
items = [s.array[i] for i in range(3)]
|
||||
self.failUnlessEqual(items, [1, 2, 3])
|
||||
|
||||
# The following are bugs, but are included here because the unittests
|
||||
# also describe the current behaviour.
|
||||
#
|
||||
# This fails with SystemError: bad arg to internal function
|
||||
# or with IndexError (with a patch I have)
|
||||
|
||||
s.array[0] = 42
|
||||
|
||||
items = [s.array[i] for i in range(3)]
|
||||
self.failUnlessEqual(items, [42, 2, 3])
|
||||
|
||||
s.array[0] = 1
|
||||
|
||||
## s.array[1] = 42
|
||||
|
||||
items = [s.array[i] for i in range(3)]
|
||||
self.failUnlessEqual(items, [1, 2, 3])
|
||||
|
||||
def test_none_to_pointer_fields(self):
|
||||
class S(Structure):
|
||||
_fields_ = [("x", c_int),
|
||||
("p", POINTER(c_int))]
|
||||
|
||||
s = S()
|
||||
s.x = 12345678
|
||||
s.p = None
|
||||
self.failUnlessEqual(s.x, 12345678)
|
||||
|
||||
class TestRecursiveStructure(unittest.TestCase):
|
||||
def test_contains_itself(self):
|
||||
class Recursive(Structure):
|
||||
pass
|
||||
|
||||
try:
|
||||
Recursive._fields_ = [("next", Recursive)]
|
||||
except AttributeError, details:
|
||||
self.failUnless("Structure or union cannot contain itself" in
|
||||
str(details))
|
||||
else:
|
||||
self.fail("Structure or union cannot contain itself")
|
||||
|
||||
|
||||
def test_vice_versa(self):
|
||||
class First(Structure):
|
||||
pass
|
||||
class Second(Structure):
|
||||
pass
|
||||
|
||||
First._fields_ = [("second", Second)]
|
||||
|
||||
try:
|
||||
Second._fields_ = [("first", First)]
|
||||
except AttributeError, details:
|
||||
self.failUnless("_fields_ is final" in
|
||||
str(details))
|
||||
else:
|
||||
self.fail("AttributeError not raised")
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -1,45 +0,0 @@
|
|||
import sys, unittest
|
||||
from ctypes import *
|
||||
|
||||
structures = []
|
||||
byteswapped_structures = []
|
||||
|
||||
|
||||
if sys.byteorder == "little":
|
||||
SwappedStructure = BigEndianStructure
|
||||
else:
|
||||
SwappedStructure = LittleEndianStructure
|
||||
|
||||
for typ in [c_short, c_int, c_long, c_longlong,
|
||||
c_float, c_double,
|
||||
c_ushort, c_uint, c_ulong, c_ulonglong]:
|
||||
class X(Structure):
|
||||
_pack_ = 1
|
||||
_fields_ = [("pad", c_byte),
|
||||
("value", typ)]
|
||||
class Y(SwappedStructure):
|
||||
_pack_ = 1
|
||||
_fields_ = [("pad", c_byte),
|
||||
("value", typ)]
|
||||
structures.append(X)
|
||||
byteswapped_structures.append(Y)
|
||||
|
||||
class TestStructures(unittest.TestCase):
|
||||
def test_native(self):
|
||||
for typ in structures:
|
||||
## print typ.value
|
||||
self.failUnlessEqual(typ.value.offset, 1)
|
||||
o = typ()
|
||||
o.value = 4
|
||||
self.failUnlessEqual(o.value, 4)
|
||||
|
||||
def test_swapped(self):
|
||||
for typ in byteswapped_structures:
|
||||
## print >> sys.stderr, typ.value
|
||||
self.failUnlessEqual(typ.value.offset, 1)
|
||||
o = typ()
|
||||
o.value = 4
|
||||
self.failUnlessEqual(o.value, 4)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -1,115 +0,0 @@
|
|||
# coding: latin-1
|
||||
import unittest
|
||||
import ctypes
|
||||
|
||||
try:
|
||||
ctypes.c_wchar
|
||||
except AttributeError:
|
||||
pass
|
||||
else:
|
||||
import _ctypes_test
|
||||
dll = ctypes.CDLL(_ctypes_test.__file__)
|
||||
wcslen = dll.my_wcslen
|
||||
wcslen.argtypes = [ctypes.c_wchar_p]
|
||||
|
||||
|
||||
class UnicodeTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.prev_conv_mode = ctypes.set_conversion_mode("ascii", "strict")
|
||||
|
||||
def tearDown(self):
|
||||
ctypes.set_conversion_mode(*self.prev_conv_mode)
|
||||
|
||||
def test_ascii_strict(self):
|
||||
ctypes.set_conversion_mode("ascii", "strict")
|
||||
# no conversions take place with unicode arguments
|
||||
self.failUnlessEqual(wcslen(u"abc"), 3)
|
||||
self.failUnlessEqual(wcslen(u"ab\u2070"), 3)
|
||||
# string args are converted
|
||||
self.failUnlessEqual(wcslen("abc"), 3)
|
||||
self.failUnlessRaises(ctypes.ArgumentError, wcslen, "abä")
|
||||
|
||||
def test_ascii_replace(self):
|
||||
ctypes.set_conversion_mode("ascii", "replace")
|
||||
self.failUnlessEqual(wcslen(u"abc"), 3)
|
||||
self.failUnlessEqual(wcslen(u"ab\u2070"), 3)
|
||||
self.failUnlessEqual(wcslen("abc"), 3)
|
||||
self.failUnlessEqual(wcslen("abä"), 3)
|
||||
|
||||
def test_ascii_ignore(self):
|
||||
ctypes.set_conversion_mode("ascii", "ignore")
|
||||
self.failUnlessEqual(wcslen(u"abc"), 3)
|
||||
self.failUnlessEqual(wcslen(u"ab\u2070"), 3)
|
||||
# ignore error mode skips non-ascii characters
|
||||
self.failUnlessEqual(wcslen("abc"), 3)
|
||||
self.failUnlessEqual(wcslen("äöüß"), 0)
|
||||
|
||||
def test_latin1_strict(self):
|
||||
ctypes.set_conversion_mode("latin-1", "strict")
|
||||
self.failUnlessEqual(wcslen(u"abc"), 3)
|
||||
self.failUnlessEqual(wcslen(u"ab\u2070"), 3)
|
||||
self.failUnlessEqual(wcslen("abc"), 3)
|
||||
self.failUnlessEqual(wcslen("äöüß"), 4)
|
||||
|
||||
def test_buffers(self):
|
||||
ctypes.set_conversion_mode("ascii", "strict")
|
||||
buf = ctypes.create_unicode_buffer("abc")
|
||||
self.failUnlessEqual(len(buf), 3+1)
|
||||
|
||||
ctypes.set_conversion_mode("ascii", "replace")
|
||||
buf = ctypes.create_unicode_buffer("abäöü")
|
||||
self.failUnlessEqual(buf[:], u"ab\uFFFD\uFFFD\uFFFD\0")
|
||||
|
||||
ctypes.set_conversion_mode("ascii", "ignore")
|
||||
buf = ctypes.create_unicode_buffer("abäöü")
|
||||
# is that correct? not sure. But with 'ignore', you get what you pay for..
|
||||
self.failUnlessEqual(buf[:], u"ab\0\0\0\0")
|
||||
|
||||
import _ctypes_test
|
||||
func = ctypes.CDLL(_ctypes_test.__file__)._testfunc_p_p
|
||||
|
||||
class StringTestCase(UnicodeTestCase):
|
||||
def setUp(self):
|
||||
self.prev_conv_mode = ctypes.set_conversion_mode("ascii", "strict")
|
||||
func.argtypes = [ctypes.c_char_p]
|
||||
func.restype = ctypes.c_char_p
|
||||
|
||||
def tearDown(self):
|
||||
ctypes.set_conversion_mode(*self.prev_conv_mode)
|
||||
func.argtypes = None
|
||||
func.restype = ctypes.c_int
|
||||
|
||||
def test_ascii_replace(self):
|
||||
ctypes.set_conversion_mode("ascii", "strict")
|
||||
self.failUnlessEqual(func("abc"), "abc")
|
||||
self.failUnlessEqual(func(u"abc"), "abc")
|
||||
self.assertRaises(ctypes.ArgumentError, func, u"abä")
|
||||
|
||||
def test_ascii_ignore(self):
|
||||
ctypes.set_conversion_mode("ascii", "ignore")
|
||||
self.failUnlessEqual(func("abc"), "abc")
|
||||
self.failUnlessEqual(func(u"abc"), "abc")
|
||||
self.failUnlessEqual(func(u"äöüß"), "")
|
||||
|
||||
def test_ascii_replace(self):
|
||||
ctypes.set_conversion_mode("ascii", "replace")
|
||||
self.failUnlessEqual(func("abc"), "abc")
|
||||
self.failUnlessEqual(func(u"abc"), "abc")
|
||||
self.failUnlessEqual(func(u"äöüß"), "????")
|
||||
|
||||
def test_buffers(self):
|
||||
ctypes.set_conversion_mode("ascii", "strict")
|
||||
buf = ctypes.create_string_buffer(u"abc")
|
||||
self.failUnlessEqual(len(buf), 3+1)
|
||||
|
||||
ctypes.set_conversion_mode("ascii", "replace")
|
||||
buf = ctypes.create_string_buffer(u"abäöü")
|
||||
self.failUnlessEqual(buf[:], "ab???\0")
|
||||
|
||||
ctypes.set_conversion_mode("ascii", "ignore")
|
||||
buf = ctypes.create_string_buffer(u"abäöü")
|
||||
# is that correct? not sure. But with 'ignore', you get what you pay for..
|
||||
self.failUnlessEqual(buf[:], "ab\0\0\0\0")
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -1,82 +0,0 @@
|
|||
"""
|
||||
A testcase which accesses *values* in a dll.
|
||||
"""
|
||||
|
||||
import unittest
|
||||
from ctypes import *
|
||||
|
||||
import _ctypes_test
|
||||
|
||||
class ValuesTestCase(unittest.TestCase):
|
||||
|
||||
def test_an_integer(self):
|
||||
ctdll = CDLL(_ctypes_test.__file__)
|
||||
an_integer = c_int.in_dll(ctdll, "an_integer")
|
||||
x = an_integer.value
|
||||
self.failUnlessEqual(x, ctdll.get_an_integer())
|
||||
an_integer.value *= 2
|
||||
self.failUnlessEqual(x*2, ctdll.get_an_integer())
|
||||
|
||||
def test_undefined(self):
|
||||
ctdll = CDLL(_ctypes_test.__file__)
|
||||
self.assertRaises(ValueError, c_int.in_dll, ctdll, "Undefined_Symbol")
|
||||
|
||||
class Win_ValuesTestCase(unittest.TestCase):
|
||||
"""This test only works when python itself is a dll/shared library"""
|
||||
|
||||
def test_optimizeflag(self):
|
||||
# This test accesses the Py_OptimizeFlag intger, which is
|
||||
# exported by the Python dll.
|
||||
|
||||
# It's value is set depending on the -O and -OO flags:
|
||||
# if not given, it is 0 and __debug__ is 1.
|
||||
# If -O is given, the flag is 1, for -OO it is 2.
|
||||
# docstrings are also removed in the latter case.
|
||||
opt = c_int.in_dll(pydll, "Py_OptimizeFlag").value
|
||||
if __debug__:
|
||||
self.failUnlessEqual(opt, 0)
|
||||
elif ValuesTestCase.__doc__ is not None:
|
||||
self.failUnlessEqual(opt, 1)
|
||||
else:
|
||||
self.failUnlessEqual(opt, 2)
|
||||
|
||||
def test_frozentable(self):
|
||||
# Python exports a PyImport_FrozenModules symbol. This is a
|
||||
# pointer to an array of struct _frozen entries. The end of the
|
||||
# array is marked by an entry containing a NULL name and zero
|
||||
# size.
|
||||
|
||||
# In standard Python, this table contains a __hello__
|
||||
# module, and a __phello__ package containing a spam
|
||||
# module.
|
||||
class struct_frozen(Structure):
|
||||
_fields_ = [("name", c_char_p),
|
||||
("code", POINTER(c_ubyte)),
|
||||
("size", c_int)]
|
||||
FrozenTable = POINTER(struct_frozen)
|
||||
|
||||
ft = FrozenTable.in_dll(pydll, "PyImport_FrozenModules")
|
||||
# ft is a pointer to the struct_frozen entries:
|
||||
items = []
|
||||
for entry in ft:
|
||||
# This is dangerous. We *can* iterate over a pointer, but
|
||||
# the loop will not terminate (maybe with an access
|
||||
# violation;-) because the pointer instance has no size.
|
||||
if entry.name is None:
|
||||
break
|
||||
items.append((entry.name, entry.size))
|
||||
import sys
|
||||
if sys.version_info[:2] >= (2, 3):
|
||||
expected = [("__hello__", 104), ("__phello__", -104), ("__phello__.spam", 104)]
|
||||
else:
|
||||
expected = [("__hello__", 100), ("__phello__", -100), ("__phello__.spam", 100)]
|
||||
self.failUnlessEqual(items, expected)
|
||||
|
||||
from ctypes import _pointer_type_cache
|
||||
del _pointer_type_cache[struct_frozen]
|
||||
|
||||
def test_undefined(self):
|
||||
self.assertRaises(ValueError, c_int.in_dll, pydll, "Undefined_Symbol")
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -1,50 +0,0 @@
|
|||
from ctypes import *
|
||||
import unittest
|
||||
|
||||
class VarSizeTest(unittest.TestCase):
|
||||
def test_resize(self):
|
||||
class X(Structure):
|
||||
_fields_ = [("item", c_int),
|
||||
("array", c_int * 1)]
|
||||
|
||||
self.failUnlessEqual(sizeof(X), sizeof(c_int) * 2)
|
||||
x = X()
|
||||
x.item = 42
|
||||
x.array[0] = 100
|
||||
self.failUnlessEqual(sizeof(x), sizeof(c_int) * 2)
|
||||
|
||||
# make room for one additional item
|
||||
new_size = sizeof(X) + sizeof(c_int) * 1
|
||||
resize(x, new_size)
|
||||
self.failUnlessEqual(sizeof(x), new_size)
|
||||
self.failUnlessEqual((x.item, x.array[0]), (42, 100))
|
||||
|
||||
# make room for 10 additional items
|
||||
new_size = sizeof(X) + sizeof(c_int) * 9
|
||||
resize(x, new_size)
|
||||
self.failUnlessEqual(sizeof(x), new_size)
|
||||
self.failUnlessEqual((x.item, x.array[0]), (42, 100))
|
||||
|
||||
# make room for one additional item
|
||||
new_size = sizeof(X) + sizeof(c_int) * 1
|
||||
resize(x, new_size)
|
||||
self.failUnlessEqual(sizeof(x), new_size)
|
||||
self.failUnlessEqual((x.item, x.array[0]), (42, 100))
|
||||
|
||||
def test_array_invalid_length(self):
|
||||
# cannot create arrays with non-positive size
|
||||
self.failUnlessRaises(ValueError, lambda: c_int * -1)
|
||||
self.failUnlessRaises(ValueError, lambda: c_int * -3)
|
||||
|
||||
def test_zerosized_array(self):
|
||||
array = (c_int * 0)()
|
||||
# accessing elements of zero-sized arrays raise IndexError
|
||||
self.failUnlessRaises(IndexError, array.__setitem__, 0, None)
|
||||
self.failUnlessRaises(IndexError, array.__getitem__, 0)
|
||||
self.failUnlessRaises(IndexError, array.__setitem__, 1, None)
|
||||
self.failUnlessRaises(IndexError, array.__getitem__, 1)
|
||||
self.failUnlessRaises(IndexError, array.__setitem__, -1, None)
|
||||
self.failUnlessRaises(IndexError, array.__getitem__, -1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
|
@ -1,60 +0,0 @@
|
|||
# Windows specific tests
|
||||
|
||||
from ctypes import *
|
||||
from ctypes.test import is_resource_enabled
|
||||
import unittest, sys
|
||||
|
||||
import _ctypes_test
|
||||
|
||||
if sys.platform == "win32":
|
||||
|
||||
class WindowsTestCase(unittest.TestCase):
|
||||
def test_callconv_1(self):
|
||||
# Testing stdcall function
|
||||
|
||||
IsWindow = windll.user32.IsWindow
|
||||
# ValueError: Procedure probably called with not enough arguments (4 bytes missing)
|
||||
self.assertRaises(ValueError, IsWindow)
|
||||
|
||||
# This one should succeeed...
|
||||
self.failUnlessEqual(0, IsWindow(0))
|
||||
|
||||
# ValueError: Procedure probably called with too many arguments (8 bytes in excess)
|
||||
self.assertRaises(ValueError, IsWindow, 0, 0, 0)
|
||||
|
||||
def test_callconv_2(self):
|
||||
# Calling stdcall function as cdecl
|
||||
|
||||
IsWindow = cdll.user32.IsWindow
|
||||
|
||||
# ValueError: Procedure called with not enough arguments (4 bytes missing)
|
||||
# or wrong calling convention
|
||||
self.assertRaises(ValueError, IsWindow, None)
|
||||
|
||||
if is_resource_enabled("SEH"):
|
||||
def test_SEH(self):
|
||||
# Call functions with invalid arguments, and make sure that access violations
|
||||
# are trapped and raise an exception.
|
||||
self.assertRaises(WindowsError, windll.kernel32.GetModuleHandleA, 32)
|
||||
|
||||
class Structures(unittest.TestCase):
|
||||
|
||||
def test_struct_by_value(self):
|
||||
class POINT(Structure):
|
||||
_fields_ = [("x", c_long),
|
||||
("y", c_long)]
|
||||
|
||||
class RECT(Structure):
|
||||
_fields_ = [("left", c_long),
|
||||
("top", c_long),
|
||||
("right", c_long),
|
||||
("bottom", c_long)]
|
||||
|
||||
dll = CDLL(_ctypes_test.__file__)
|
||||
|
||||
pt = POINT(10, 10)
|
||||
rect = RECT(0, 0, 20, 20)
|
||||
self.failUnlessEqual(1, dll.PointInRect(byref(rect), pt))
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
Binary file not shown.
Before Width: | Height: | Size: 954 B |
Binary file not shown.
|
@ -1,19 +0,0 @@
|
|||
Return-Path: <bbb@zzz.org>
|
||||
Delivered-To: bbb@zzz.org
|
||||
Received: by mail.zzz.org (Postfix, from userid 889)
|
||||
id 27CEAD38CC; Fri, 4 May 2001 14:05:44 -0400 (EDT)
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=us-ascii
|
||||
Content-Transfer-Encoding: 7bit
|
||||
Message-ID: <15090.61304.110929.45684@aaa.zzz.org>
|
||||
From: bbb@ddd.com (John X. Doe)
|
||||
To: bbb@zzz.org
|
||||
Subject: This is a test message
|
||||
Date: Fri, 4 May 2001 14:05:44 -0400
|
||||
|
||||
|
||||
Hi,
|
||||
|
||||
Do you like this message?
|
||||
|
||||
-Me
|
|
@ -1,135 +0,0 @@
|
|||
MIME-version: 1.0
|
||||
From: ppp-request@zzz.org
|
||||
Sender: ppp-admin@zzz.org
|
||||
To: ppp@zzz.org
|
||||
Subject: Ppp digest, Vol 1 #2 - 5 msgs
|
||||
Date: Fri, 20 Apr 2001 20:18:00 -0400 (EDT)
|
||||
X-Mailer: Mailman v2.0.4
|
||||
X-Mailman-Version: 2.0.4
|
||||
Content-Type: multipart/mixed; boundary="192.168.1.2.889.32614.987812255.500.21814"
|
||||
|
||||
--192.168.1.2.889.32614.987812255.500.21814
|
||||
Content-type: text/plain; charset=us-ascii
|
||||
Content-description: Masthead (Ppp digest, Vol 1 #2)
|
||||
|
||||
Send Ppp mailing list submissions to
|
||||
ppp@zzz.org
|
||||
|
||||
To subscribe or unsubscribe via the World Wide Web, visit
|
||||
http://www.zzz.org/mailman/listinfo/ppp
|
||||
or, via email, send a message with subject or body 'help' to
|
||||
ppp-request@zzz.org
|
||||
|
||||
You can reach the person managing the list at
|
||||
ppp-admin@zzz.org
|
||||
|
||||
When replying, please edit your Subject line so it is more specific
|
||||
than "Re: Contents of Ppp digest..."
|
||||
|
||||
|
||||
--192.168.1.2.889.32614.987812255.500.21814
|
||||
Content-type: text/plain; charset=us-ascii
|
||||
Content-description: Today's Topics (5 msgs)
|
||||
|
||||
Today's Topics:
|
||||
|
||||
1. testing #1 (Barry A. Warsaw)
|
||||
2. testing #2 (Barry A. Warsaw)
|
||||
3. testing #3 (Barry A. Warsaw)
|
||||
4. testing #4 (Barry A. Warsaw)
|
||||
5. testing #5 (Barry A. Warsaw)
|
||||
|
||||
--192.168.1.2.889.32614.987812255.500.21814
|
||||
Content-Type: multipart/digest; boundary="__--__--"
|
||||
|
||||
--__--__--
|
||||
|
||||
Message: 1
|
||||
Content-Type: text/plain; charset=us-ascii
|
||||
Content-Transfer-Encoding: 7bit
|
||||
Date: Fri, 20 Apr 2001 20:16:13 -0400
|
||||
To: ppp@zzz.org
|
||||
From: barry@digicool.com (Barry A. Warsaw)
|
||||
Subject: [Ppp] testing #1
|
||||
Precedence: bulk
|
||||
|
||||
|
||||
hello
|
||||
|
||||
|
||||
--__--__--
|
||||
|
||||
Message: 2
|
||||
Date: Fri, 20 Apr 2001 20:16:21 -0400
|
||||
Content-Type: text/plain; charset=us-ascii
|
||||
Content-Transfer-Encoding: 7bit
|
||||
To: ppp@zzz.org
|
||||
From: barry@digicool.com (Barry A. Warsaw)
|
||||
Precedence: bulk
|
||||
|
||||
|
||||
hello
|
||||
|
||||
|
||||
--__--__--
|
||||
|
||||
Message: 3
|
||||
Date: Fri, 20 Apr 2001 20:16:25 -0400
|
||||
Content-Type: text/plain; charset=us-ascii
|
||||
Content-Transfer-Encoding: 7bit
|
||||
To: ppp@zzz.org
|
||||
From: barry@digicool.com (Barry A. Warsaw)
|
||||
Subject: [Ppp] testing #3
|
||||
Precedence: bulk
|
||||
|
||||
|
||||
hello
|
||||
|
||||
|
||||
--__--__--
|
||||
|
||||
Message: 4
|
||||
Date: Fri, 20 Apr 2001 20:16:28 -0400
|
||||
Content-Type: text/plain; charset=us-ascii
|
||||
Content-Transfer-Encoding: 7bit
|
||||
To: ppp@zzz.org
|
||||
From: barry@digicool.com (Barry A. Warsaw)
|
||||
Subject: [Ppp] testing #4
|
||||
Precedence: bulk
|
||||
|
||||
|
||||
hello
|
||||
|
||||
|
||||
--__--__--
|
||||
|
||||
Message: 5
|
||||
Date: Fri, 20 Apr 2001 20:16:32 -0400
|
||||
Content-Type: text/plain; charset=us-ascii
|
||||
Content-Transfer-Encoding: 7bit
|
||||
To: ppp@zzz.org
|
||||
From: barry@digicool.com (Barry A. Warsaw)
|
||||
Subject: [Ppp] testing #5
|
||||
Precedence: bulk
|
||||
|
||||
|
||||
hello
|
||||
|
||||
|
||||
|
||||
|
||||
--__--__----
|
||||
--192.168.1.2.889.32614.987812255.500.21814
|
||||
Content-type: text/plain; charset=us-ascii
|
||||
Content-description: Digest Footer
|
||||
|
||||
_______________________________________________
|
||||
Ppp mailing list
|
||||
Ppp@zzz.org
|
||||
http://www.zzz.org/mailman/listinfo/ppp
|
||||
|
||||
|
||||
--192.168.1.2.889.32614.987812255.500.21814--
|
||||
|
||||
End of Ppp Digest
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
Return-Path: <bbb@zzz.org>
|
||||
Delivered-To: bbb@zzz.org
|
||||
Received: by mail.zzz.org (Postfix, from userid 889)
|
||||
id 27CEAD38CC; Fri, 4 May 2001 14:05:44 -0400 (EDT)
|
||||
Message-ID: <15090.61304.110929.45684@aaa.zzz.org>
|
||||
From: bbb@ddd.com (John X. Doe)
|
||||
To: bbb@zzz.org
|
||||
Subject: This is a test message
|
||||
Date: Fri, 4 May 2001 14:05:44 -0400
|
||||
|
||||
|
||||
Hi,
|
||||
|
||||
Do you like this message?
|
||||
|
||||
-Me
|
|
@ -1,37 +0,0 @@
|
|||
Return-Path: <barry@python.org>
|
||||
Delivered-To: barry@python.org
|
||||
Received: by mail.python.org (Postfix, from userid 889)
|
||||
id C2BF0D37C6; Tue, 11 Sep 2001 00:05:05 -0400 (EDT)
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/mixed; boundary="h90VIIIKmx"
|
||||
Content-Transfer-Encoding: 7bit
|
||||
Message-ID: <15261.36209.358846.118674@anthem.python.org>
|
||||
From: barry@python.org (Barry A. Warsaw)
|
||||
To: barry@python.org
|
||||
Subject: a simple multipart
|
||||
Date: Tue, 11 Sep 2001 00:05:05 -0400
|
||||
X-Mailer: VM 6.95 under 21.4 (patch 4) "Artificial Intelligence" XEmacs Lucid
|
||||
X-Attribution: BAW
|
||||
X-Oblique-Strategy: Make a door into a window
|
||||
|
||||
|
||||
--h90VIIIKmx
|
||||
Content-Type: text/plain
|
||||
Content-Disposition: inline;
|
||||
filename="msg.txt"
|
||||
Content-Transfer-Encoding: 7bit
|
||||
|
||||
a simple kind of mirror
|
||||
to reflect upon our own
|
||||
|
||||
--h90VIIIKmx
|
||||
Content-Type: text/plain
|
||||
Content-Disposition: inline;
|
||||
filename="msg.txt"
|
||||
Content-Transfer-Encoding: 7bit
|
||||
|
||||
a simple kind of mirror
|
||||
to reflect upon our own
|
||||
|
||||
--h90VIIIKmx--
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
From: foo
|
||||
Subject: bar
|
||||
To: baz
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/report; report-type=delivery-status;
|
||||
boundary="D1690A7AC1.996856090/mail.example.com"
|
||||
Message-Id: <20010803162810.0CA8AA7ACC@mail.example.com>
|
||||
|
||||
This is a MIME-encapsulated message.
|
||||
|
||||
--D1690A7AC1.996856090/mail.example.com
|
||||
Content-Type: text/plain
|
||||
|
||||
Yadda yadda yadda
|
||||
|
||||
--D1690A7AC1.996856090/mail.example.com
|
||||
|
||||
Yadda yadda yadda
|
||||
|
||||
--D1690A7AC1.996856090/mail.example.com
|
||||
Content-Type: message/rfc822
|
||||
|
||||
From: nobody@python.org
|
||||
|
||||
Yadda yadda yadda
|
||||
|
||||
--D1690A7AC1.996856090/mail.example.com--
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
Return-Path: <barry@python.org>
|
||||
Delivered-To: barry@python.org
|
||||
MIME-Version: 1.0
|
||||
Content-Type: message/rfc822
|
||||
Content-Description: forwarded message
|
||||
Content-Transfer-Encoding: 7bit
|
||||
Message-ID: <15265.9482.641338.555352@python.org>
|
||||
From: barry@zope.com (Barry A. Warsaw)
|
||||
Sender: barry@python.org
|
||||
To: barry@python.org
|
||||
Subject: forwarded message from Barry A. Warsaw
|
||||
Date: Thu, 13 Sep 2001 17:28:42 -0400
|
||||
X-Mailer: VM 6.95 under 21.4 (patch 4) "Artificial Intelligence" XEmacs Lucid
|
||||
X-Attribution: BAW
|
||||
X-Oblique-Strategy: Be dirty
|
||||
X-Url: http://barry.wooz.org
|
||||
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=us-ascii
|
||||
Return-Path: <barry@python.org>
|
||||
Delivered-To: barry@python.org
|
||||
Message-ID: <15265.9468.713530.98441@python.org>
|
||||
From: barry@zope.com (Barry A. Warsaw)
|
||||
Sender: barry@python.org
|
||||
To: barry@python.org
|
||||
Subject: testing
|
||||
Date: Thu, 13 Sep 2001 17:28:28 -0400
|
||||
X-Mailer: VM 6.95 under 21.4 (patch 4) "Artificial Intelligence" XEmacs Lucid
|
||||
X-Attribution: BAW
|
||||
X-Oblique-Strategy: Spectrum analysis
|
||||
X-Url: http://barry.wooz.org
|
||||
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
MIME-Version: 1.0
|
||||
From: Barry <barry@digicool.com>
|
||||
To: Dingus Lovers <cravindogs@cravindogs.com>
|
||||
Subject: Here is your dingus fish
|
||||
Date: Fri, 20 Apr 2001 19:35:02 -0400
|
||||
Content-Type: multipart/mixed; boundary="BOUNDARY"
|
||||
|
||||
--BOUNDARY
|
||||
Content-Type: text/plain; charset="us-ascii"
|
||||
|
||||
Hi there,
|
||||
|
||||
This is the dingus fish.
|
||||
|
||||
--BOUNDARY
|
||||
Content-Type: image/gif; name="dingusfish.gif"
|
||||
Content-Transfer-Encoding: base64
|
||||
content-disposition: attachment; filename="dingusfish.gif"
|
||||
|
||||
R0lGODdhAAEAAfAAAP///wAAACwAAAAAAAEAAQAC/oSPqcvtD6OctNqLs968+w+G4kiW5omm6sq2
|
||||
7gvH8kzX9o3n+s73/g8MCofEovGITGICTKbyCV0FDNOo9SqpQqpOrJfXzTQj2vD3TGtqL+NtGQ2f
|
||||
qTXmxzuOd7WXdcc9DyjU53ewFni4s0fGhdiYaEhGBelICTNoV1j5NUnFcrmUqemjNifJVWpaOqaI
|
||||
oFq3SspZsSraE7sHq3jr1MZqWvi662vxV4tD+pvKW6aLDOCLyur8PDwbanyDeq0N3DctbQYeLDvR
|
||||
RY6t95m6UB0d3mwIrV7e2VGNvjjffukeJp4w7F65KecGFsTHQGAygOrgrWs1jt28Rc88KESYcGLA
|
||||
/obvTkH6p+CinWJiJmIMqXGQwH/y4qk0SYjgQTczT3ajKZGfuI0uJ4kkVI/DT5s3/ejkxI0aT4Y+
|
||||
YTYgWbImUaXk9nlLmnSh1qJiJFl0OpUqRK4oOy7NyRQtHWofhoYVxkwWXKUSn0YsS+fUV6lhqfYb
|
||||
6ayd3Z5qQdG1B7bvQzaJjwUV2lixMUZ7JVsOlfjWVr/3NB/uFvnySBN6Dcb6rGwaRM3wsormw5cC
|
||||
M9NxWy/bWdufudCvy8bOAjXjVVwta/uO21sE5RHBCzNFXtgq9ORtH4eYjVP4Yryo026nvkFmCeyA
|
||||
B29efV6ravCMK5JwWd5897Qrx7ll38o6iHDZ/rXPR//feevhF4l7wjUGX3xq1eeRfM4RSJGBIV1D
|
||||
z1gKPkfWag3mVBVvva1RlX5bAJTPR/2YqNtw/FkIYYEi/pIZiAdpcxpoHtmnYYoZtvhUftzdx5ZX
|
||||
JSKDW405zkGcZzzGZ6KEv4FI224oDmijlEf+xp6MJK5ojY/ASeVUR+wsKRuJ+XFZ5o7ZeEime8t1
|
||||
ouUsU6YjF5ZtUihhkGfCdFQLWQFJ3UXxmElfhQnR+eCdcDbkFZp6vTRmj56ApCihn5QGpaToNZmR
|
||||
n3NVSpZcQpZ2KEONusaiCsKAug0wkQbJSFO+PTSjneGxOuFjPlUk3ovWvdIerjUg9ZGIOtGq/qeX
|
||||
eCYrrCX+1UPsgTKGGRSbzd5q156d/gpfbJxe66eD5iQKrXj7RGgruGxs62qebBHUKS32CKluCiqZ
|
||||
qh+pmehmEb71noAUoe5e9Zm17S7773V10pjrtG4CmuurCV/n6zLK5turWNhqOvFXbjhZrMD0YhKe
|
||||
wR0zOyuvsh6MWrGoIuzvyWu5y1WIFAqmJselypxXh6dKLNOKEB98L88bS2rkNqqlKzCNJp9c0G0j
|
||||
Gzh0iRrCbHSXmPR643QS+4rWhgFmnSbSuXCjS0xAOWkU2UdLqyuUNfHSFdUouy3bm5i5GnDM3tG8
|
||||
doJ4r5tqu3pPbRSVfvs8uJzeNXhp3n4j/tZ42SwH7eaWUUOjc3qFV9453UHTXZfcLH+OeNs5g36x
|
||||
lBnHvTm7EbMbLeuaLncao8vWCXimfo1o+843Ak6y4ChNeGntvAYvfLK4ezmoyNIbNCLTCXO9ZV3A
|
||||
E8/s88RczPzDwI4Ob7XZyl7+9Miban29h+tJZPrE21wgvBphDfrrfPdCTPKJD/y98L1rZwHcV6Jq
|
||||
Zab0metpuNIX/qAFPoz171WUaUb4HAhBSzHuHfjzHb3kha/2Cctis/ORArVHNYfFyYRH2pYIRzic
|
||||
isVOfPWD1b6mRTqpCRBozzof6UZVvFXRxWIr3GGrEviGYgyPMfahheiSaLs/9QeFu7oZ/ndSY8DD
|
||||
ya9x+uPed+7mxN2IzIISBOMLFYWVqC3Pew1T2nFuuCiwZS5/v6II10i4t1OJcUH2U9zxKodHsGGv
|
||||
Oa+zkvNUYUOa/TCCRutF9MzDwdlUMJADTCGSbDQ5OV4PTamDoPEi6Ecc/RF5RWwkcdSXvSOaDWSn
|
||||
I9LlvubFTQpuc6JKXLcKeb+xdbKRBnwREemXyjg6ME65aJiOuBgrktzykfPLJBKR9ClMavJ62/Ff
|
||||
BlNIyod9yX9wcSXexnXFpvkrbXk64xsx5Db7wXKP5fSgsvwIMM/9631VLBfkmtbHRXpqmtei52hG
|
||||
pUwSlo+BASQoeILDOBgREECxBBh5/iYmNsQ9dIv5+OI++QkqdsJPc3uykz5fkM+OraeekcQF7X4n
|
||||
B5S67za5U967PmooGQhUXfF7afXyCD7ONdRe17QogYjVx38uLwtrS6nhTnm15LQUnu9E2uK6CNI/
|
||||
1HOABj0ESwOjut4FEpFQpdNAm4K2LHnDWHNcmKB2ioKBogysVZtMO2nSxUdZ8Yk2kJc7URioLVI0
|
||||
YgmtIwZj4LoeKemgnOnbUdGnzZ4Oa6scqiolBGqS6RgWNLu0RMhcaE6rhhU4hiuqFXPAG8fGwTPW
|
||||
FKeLMtdVmXLSs5YJGF/YeVm7rREMlY3UYE+yCxbaMXX8y15m5zVHq6GOKDMynzII/jdUHdyVqIy0
|
||||
ifX2+r/EgtZcvRzSb72gU9ui87M2VecjKildW/aFqaYhKoryUjfB/g4qtyVuc60xFDGmCxwjW+qu
|
||||
zjuwl2GkOWn66+3QiiEctvd04OVvcCVzjgT7lrkvjVGKKHmmlDUKowSeikb5kK/mJReuWOxONx+s
|
||||
ULsl+Lqb0CVn0SrVyJ6wt4t6yTeSCafhPhAf0OXn6L60UMxiLolFAtmN35S2Ob1lZpQ1r/n0Qb5D
|
||||
oQ1zJiRVDgF8N3Q8TYfbi3DyWCy3lT1nxyBs6FT3S2GOzWRlxwKvlRP0RPJA9SjxEy0UoEnkA+M4
|
||||
cnzLMJrBGWLFEaaUb5lvpqbq/loOaU5+DFuHPxo82/OZuM8FXG3oVNZhtWpMpb/0Xu5m/LfLhHZQ
|
||||
7yuVI0MqZ7NE43imC8jH3IwGZlbPm0xkJYs7+2U48hXTsFSMqgGDvai0kLxyynKNT/waj+q1c1tz
|
||||
GjOpPBgdCSq3UKZxCSsqFIY+O6JbAWGWcV1pwqLyj5sGqCF1xb1F3varUWqrJv6cN3PrUXzijtfZ
|
||||
FshpBL3Xwr4GIPvU2N8EjrJgS1zl21rbXQMXeXc5jjFyrhpCzijSv/RQtyPSzHCFMhlME95fHglt
|
||||
pRsX+dfSQjUeHAlpWzJ5iOo79Ldnaxai6bXTcGO3fp07ri7HLEmXXPlYi8bv/qVxvNcdra6m7Rlb
|
||||
6JBTb5fd66VhFRjGArh2n7R1rDW4P5NOT9K0I183T2scYkeZ3q/VFyLb09U9ajzXBS8Kgkhc4mBS
|
||||
kYY9cy3Vy9lUnuNJH8HGIclUilwnBtjUOH0gteGOZ4c/XNrhXLSYDyxfnD8z1pDy7rYRvDolhnbe
|
||||
UMzxCZUs40s6s7UIvBnLgc0+vKuOkIXeOrDymlp+Zxra4MZLBbVrqD/jTJ597pDmnw5c4+DbyB88
|
||||
9Cg9DodYcSuMZT/114pptqc/EuTjRPvH/z5slzI3tluOEBBLqOXLOX+0I5929tO97wkvl/atCz+y
|
||||
xJrdwteW2FNW/NSmBP+f/maYtVs/bYyBC7Ox3jsYZHL05CIrBa/nS+b3bHfiYm4Ueil1YZZSgAUI
|
||||
fFZ1dxUmeA2oQRQ3RuGXNGLFV9/XbGFGPV6kfzk1TBBCd+izc7q1H+OHMJwmaBX2IQNYVAKHYepV
|
||||
SSGCe6CnbYHHETKGNe43EDvFgZr0gB/nVHPHZ80VV1ojOiI3XDvYIkl4ayo4bxQIgrFXWTvBI0nH
|
||||
VElWMuw2aLUWCRHHf8ymVCHjFlJnOSojfevCYyyyZDH0IcvHhrsnQ5O1OsWzONuVVKIxSxiFZ/tR
|
||||
fKDAf6xFTnw4O9Qig2VCfW2hJQrmMOuHW0W3dLQmCMO2ccdUd/xyfflH/olTiHZVdGwb8nIwRzSE
|
||||
J15jFlOJuBZBZ4CiyHyd2IFylFlB+HgHhYabhWOGwYO1ZH/Og1dtQlFMk352CGRSIFTapnWQEUtN
|
||||
l4zv8S0aaCFDyGCBqDUxZYpxGHX01y/JuH1xhn7TOCnNCI4eKDs5WGX4R425F4vF1o3BJ4vO0otq
|
||||
I3rimI7jJY1jISqnBxknCIvruF83mF5wN4X7qGLIhR8A2Vg0yFERSIXn9Vv3GHy3Vj/WIkKddlYi
|
||||
yIMv2I/VMjTLpW7pt05SWIZR0RPyxpB4SIUM9lBPGBl0GC7oSEEwRYLe4pJpZY2P0zbI1n+Oc44w
|
||||
qY3PUnmF0ixjVpDD/mJ9wpOBGTVgXlaCaZiPcIWK5NiKBIiPdGaQ0TWGvAiG7nMchdZb7Vgf8zNi
|
||||
MuMyzRdy/lePe9iC4TRx7WhhOQI/QiSVNAmAa2lT/piFbuh7ofJoYSZzrSZ1bvmWw3eN2nKUPVky
|
||||
uPN5/VRfohRd0VYZoqhKIlU6TXYhJxmPUIloAwc1bPmHEpaZYZORHNlXUJM07hATwHR8MJYqkwWR
|
||||
WaIezFhxSFlc8/Fq82hEnpeRozg3ULhhr9lAGtVEkCg5ZNRuuVleBPaZadhG0ZgkyPmDOTOKzViM
|
||||
YgOcpukKqQcbjAWS0IleQ2ROjdh6A+md1qWdBRSX7iSYgFRTtRmBpJioieXJiHfJiMGIR9fJOn8I
|
||||
MSfXYhspn4ooSa2mSAj4n+8Bmg03fBJZoPOJgsVZRxu1oOMRPXYYjdqjihFaEoZpXBREanuJoRI6
|
||||
cibFinq4ngUKh/wQd/H5ofYCZ0HJXR62opZFaAT0iFIZo4DIiUojkjeqKiuoZirKo5Y1a7AWckGa
|
||||
BkuYoD5lpDK6eUs6CkDqpETwl1EqpfhJpVeKpVl6EgUAADs=
|
||||
|
||||
--BOUNDARY--
|
|
@ -1,24 +0,0 @@
|
|||
MIME-Version: 1.0
|
||||
From: Barry Warsaw <barry@zope.com>
|
||||
To: Dingus Lovers <cravindogs@cravindogs.com>
|
||||
Subject: Lyrics
|
||||
Date: Fri, 20 Apr 2001 19:35:02 -0400
|
||||
Content-Type: multipart/mixed; boundary="BOUNDARY"
|
||||
|
||||
--BOUNDARY
|
||||
Content-Type: text/plain; charset="us-ascii"
|
||||
|
||||
|
||||
--BOUNDARY
|
||||
Content-Type: text/html; charset="iso-8859-1"
|
||||
|
||||
|
||||
--BOUNDARY
|
||||
Content-Type: text/plain; charset="iso-8859-2"
|
||||
|
||||
|
||||
--BOUNDARY
|
||||
Content-Type: text/plain; charset="koi8-r"
|
||||
|
||||
|
||||
--BOUNDARY--
|
|
@ -1,24 +0,0 @@
|
|||
MIME-Version: 1.0
|
||||
From: Barry Warsaw <barry@zope.com>
|
||||
To: Dingus Lovers <cravindogs@cravindogs.com>
|
||||
Subject: Lyrics
|
||||
Date: Fri, 20 Apr 2001 19:35:02 -0400
|
||||
Content-Type: multipart/mixed; boundary="BOUNDARY"
|
||||
|
||||
--BOUNDARY
|
||||
Content-Type: text/plain; charset="us-ascii"
|
||||
|
||||
|
||||
--BOUNDARY
|
||||
Content-Type: text/html; charset="iso-8859-1"
|
||||
|
||||
|
||||
--BOUNDARY
|
||||
Content-Type: text/plain
|
||||
|
||||
|
||||
--BOUNDARY
|
||||
Content-Type: text/plain; charset="koi8-r"
|
||||
|
||||
|
||||
--BOUNDARY--
|
|
@ -1,32 +0,0 @@
|
|||
MIME-Version: 1.0
|
||||
From: Barry Warsaw <barry@zope.com>
|
||||
To: Dingus Lovers <cravindogs@cravindogs.com>
|
||||
Subject: Lyrics
|
||||
Date: Fri, 20 Apr 2001 19:35:02 -0400
|
||||
Content-Type: multipart/mixed; boundary="BOUNDARY"
|
||||
|
||||
--BOUNDARY
|
||||
Content-Type: text/plain; charset="us-ascii"
|
||||
Content-Transfer-Encoding: 7bit
|
||||
|
||||
This is a 7bit encoded message.
|
||||
|
||||
--BOUNDARY
|
||||
Content-Type: text/html; charset="iso-8859-1"
|
||||
Content-Transfer-Encoding: Quoted-Printable
|
||||
|
||||
=A1This is a Quoted Printable encoded message!
|
||||
|
||||
--BOUNDARY
|
||||
Content-Type: text/plain; charset="iso-8859-1"
|
||||
Content-Transfer-Encoding: Base64
|
||||
|
||||
VGhpcyBpcyBhIEJhc2U2NCBlbmNvZGVkIG1lc3NhZ2Uu
|
||||
|
||||
|
||||
--BOUNDARY
|
||||
Content-Type: text/plain; charset="iso-8859-1"
|
||||
|
||||
This has no Content-Transfer-Encoding: header.
|
||||
|
||||
--BOUNDARY--
|
|
@ -1,7 +0,0 @@
|
|||
Content-Type: message/rfc822
|
||||
MIME-Version: 1.0
|
||||
Subject: The enclosing message
|
||||
|
||||
Subject: An enclosed message
|
||||
|
||||
Here is the body of the message.
|
|
@ -1,36 +0,0 @@
|
|||
MIME-Version: 1.0
|
||||
From: Barry Warsaw <barry@zope.com>
|
||||
To: Dingus Lovers <cravindogs@cravindogs.com>
|
||||
Subject: Lyrics
|
||||
Date: Fri, 20 Apr 2001 19:35:02 -0400
|
||||
Content-Type: multipart/mixed; boundary="BOUNDARY"
|
||||
|
||||
--BOUNDARY
|
||||
Content-Type: text/plain; charset="us-ascii"
|
||||
|
||||
|
||||
--BOUNDARY
|
||||
Content-Type: text/html; charset="iso-8859-1"
|
||||
|
||||
|
||||
--BOUNDARY
|
||||
Content-Type: multipart/mixed; boundary="ANOTHER"
|
||||
|
||||
--ANOTHER
|
||||
Content-Type: text/plain; charset="iso-8859-2"
|
||||
|
||||
|
||||
--ANOTHER
|
||||
Content-Type: text/plain; charset="iso-8859-3"
|
||||
|
||||
--ANOTHER--
|
||||
|
||||
--BOUNDARY
|
||||
Content-Type: text/plain; charset="us-ascii"
|
||||
|
||||
|
||||
--BOUNDARY
|
||||
Content-Type: text/plain; charset="koi8-r"
|
||||
|
||||
|
||||
--BOUNDARY--
|
|
@ -1,38 +0,0 @@
|
|||
MIME-Version: 1.0
|
||||
From: Barry Warsaw <barry@zope.com>
|
||||
To: Dingus Lovers <cravindogs@cravindogs.com>
|
||||
Subject: Lyrics
|
||||
Date: Fri, 20 Apr 2001 19:35:02 -0400
|
||||
Content-Type: multipart/mixed; boundary="BOUNDARY"
|
||||
|
||||
--BOUNDARY
|
||||
Content-Type: text/plain; charset="us-ascii"
|
||||
|
||||
|
||||
--BOUNDARY
|
||||
Content-Type: text/html; charset="iso-8859-1"
|
||||
|
||||
|
||||
--BOUNDARY
|
||||
Content-Type: multipart/mixed; boundary="ANOTHER"
|
||||
|
||||
--ANOTHER
|
||||
Content-Type: text/plain; charset="iso-8859-2"
|
||||
|
||||
|
||||
--ANOTHER
|
||||
Content-Type: text/plain; charset="iso-8859-3"
|
||||
|
||||
|
||||
--ANOTHER--
|
||||
|
||||
|
||||
--BOUNDARY
|
||||
Content-Type: text/plain; charset="us-ascii"
|
||||
|
||||
|
||||
--BOUNDARY
|
||||
Content-Type: text/plain; charset="koi8-r"
|
||||
|
||||
|
||||
--BOUNDARY--
|
|
@ -1,94 +0,0 @@
|
|||
MIME-Version: 1.0
|
||||
From: Barry <barry@digicool.com>
|
||||
To: Dingus Lovers <cravindogs@cravindogs.com>
|
||||
Subject: Here is your dingus fish
|
||||
Date: Fri, 20 Apr 2001 19:35:02 -0400
|
||||
Content-Type: multipart/mixed; boundary="OUTER"
|
||||
|
||||
--OUTER
|
||||
Content-Type: text/plain; charset="us-ascii"
|
||||
|
||||
A text/plain part
|
||||
|
||||
--OUTER
|
||||
Content-Type: multipart/mixed; boundary=BOUNDARY
|
||||
|
||||
|
||||
--BOUNDARY
|
||||
Content-Type: text/plain; charset="us-ascii"
|
||||
|
||||
Hi there,
|
||||
|
||||
This is the dingus fish.
|
||||
|
||||
--BOUNDARY
|
||||
Content-Type: image/gif; name="dingusfish.gif"
|
||||
Content-Transfer-Encoding: base64
|
||||
content-disposition: attachment; filename="dingusfish.gif"
|
||||
|
||||
R0lGODdhAAEAAfAAAP///wAAACwAAAAAAAEAAQAC/oSPqcvtD6OctNqLs968+w+G4kiW5omm6sq2
|
||||
7gvH8kzX9o3n+s73/g8MCofEovGITGICTKbyCV0FDNOo9SqpQqpOrJfXzTQj2vD3TGtqL+NtGQ2f
|
||||
qTXmxzuOd7WXdcc9DyjU53ewFni4s0fGhdiYaEhGBelICTNoV1j5NUnFcrmUqemjNifJVWpaOqaI
|
||||
oFq3SspZsSraE7sHq3jr1MZqWvi662vxV4tD+pvKW6aLDOCLyur8PDwbanyDeq0N3DctbQYeLDvR
|
||||
RY6t95m6UB0d3mwIrV7e2VGNvjjffukeJp4w7F65KecGFsTHQGAygOrgrWs1jt28Rc88KESYcGLA
|
||||
/obvTkH6p+CinWJiJmIMqXGQwH/y4qk0SYjgQTczT3ajKZGfuI0uJ4kkVI/DT5s3/ejkxI0aT4Y+
|
||||
YTYgWbImUaXk9nlLmnSh1qJiJFl0OpUqRK4oOy7NyRQtHWofhoYVxkwWXKUSn0YsS+fUV6lhqfYb
|
||||
6ayd3Z5qQdG1B7bvQzaJjwUV2lixMUZ7JVsOlfjWVr/3NB/uFvnySBN6Dcb6rGwaRM3wsormw5cC
|
||||
M9NxWy/bWdufudCvy8bOAjXjVVwta/uO21sE5RHBCzNFXtgq9ORtH4eYjVP4Yryo026nvkFmCeyA
|
||||
B29efV6ravCMK5JwWd5897Qrx7ll38o6iHDZ/rXPR//feevhF4l7wjUGX3xq1eeRfM4RSJGBIV1D
|
||||
z1gKPkfWag3mVBVvva1RlX5bAJTPR/2YqNtw/FkIYYEi/pIZiAdpcxpoHtmnYYoZtvhUftzdx5ZX
|
||||
JSKDW405zkGcZzzGZ6KEv4FI224oDmijlEf+xp6MJK5ojY/ASeVUR+wsKRuJ+XFZ5o7ZeEime8t1
|
||||
ouUsU6YjF5ZtUihhkGfCdFQLWQFJ3UXxmElfhQnR+eCdcDbkFZp6vTRmj56ApCihn5QGpaToNZmR
|
||||
n3NVSpZcQpZ2KEONusaiCsKAug0wkQbJSFO+PTSjneGxOuFjPlUk3ovWvdIerjUg9ZGIOtGq/qeX
|
||||
eCYrrCX+1UPsgTKGGRSbzd5q156d/gpfbJxe66eD5iQKrXj7RGgruGxs62qebBHUKS32CKluCiqZ
|
||||
qh+pmehmEb71noAUoe5e9Zm17S7773V10pjrtG4CmuurCV/n6zLK5turWNhqOvFXbjhZrMD0YhKe
|
||||
wR0zOyuvsh6MWrGoIuzvyWu5y1WIFAqmJselypxXh6dKLNOKEB98L88bS2rkNqqlKzCNJp9c0G0j
|
||||
Gzh0iRrCbHSXmPR643QS+4rWhgFmnSbSuXCjS0xAOWkU2UdLqyuUNfHSFdUouy3bm5i5GnDM3tG8
|
||||
doJ4r5tqu3pPbRSVfvs8uJzeNXhp3n4j/tZ42SwH7eaWUUOjc3qFV9453UHTXZfcLH+OeNs5g36x
|
||||
lBnHvTm7EbMbLeuaLncao8vWCXimfo1o+843Ak6y4ChNeGntvAYvfLK4ezmoyNIbNCLTCXO9ZV3A
|
||||
E8/s88RczPzDwI4Ob7XZyl7+9Miban29h+tJZPrE21wgvBphDfrrfPdCTPKJD/y98L1rZwHcV6Jq
|
||||
Zab0metpuNIX/qAFPoz171WUaUb4HAhBSzHuHfjzHb3kha/2Cctis/ORArVHNYfFyYRH2pYIRzic
|
||||
isVOfPWD1b6mRTqpCRBozzof6UZVvFXRxWIr3GGrEviGYgyPMfahheiSaLs/9QeFu7oZ/ndSY8DD
|
||||
ya9x+uPed+7mxN2IzIISBOMLFYWVqC3Pew1T2nFuuCiwZS5/v6II10i4t1OJcUH2U9zxKodHsGGv
|
||||
Oa+zkvNUYUOa/TCCRutF9MzDwdlUMJADTCGSbDQ5OV4PTamDoPEi6Ecc/RF5RWwkcdSXvSOaDWSn
|
||||
I9LlvubFTQpuc6JKXLcKeb+xdbKRBnwREemXyjg6ME65aJiOuBgrktzykfPLJBKR9ClMavJ62/Ff
|
||||
BlNIyod9yX9wcSXexnXFpvkrbXk64xsx5Db7wXKP5fSgsvwIMM/9631VLBfkmtbHRXpqmtei52hG
|
||||
pUwSlo+BASQoeILDOBgREECxBBh5/iYmNsQ9dIv5+OI++QkqdsJPc3uykz5fkM+OraeekcQF7X4n
|
||||
B5S67za5U967PmooGQhUXfF7afXyCD7ONdRe17QogYjVx38uLwtrS6nhTnm15LQUnu9E2uK6CNI/
|
||||
1HOABj0ESwOjut4FEpFQpdNAm4K2LHnDWHNcmKB2ioKBogysVZtMO2nSxUdZ8Yk2kJc7URioLVI0
|
||||
YgmtIwZj4LoeKemgnOnbUdGnzZ4Oa6scqiolBGqS6RgWNLu0RMhcaE6rhhU4hiuqFXPAG8fGwTPW
|
||||
FKeLMtdVmXLSs5YJGF/YeVm7rREMlY3UYE+yCxbaMXX8y15m5zVHq6GOKDMynzII/jdUHdyVqIy0
|
||||
ifX2+r/EgtZcvRzSb72gU9ui87M2VecjKildW/aFqaYhKoryUjfB/g4qtyVuc60xFDGmCxwjW+qu
|
||||
zjuwl2GkOWn66+3QiiEctvd04OVvcCVzjgT7lrkvjVGKKHmmlDUKowSeikb5kK/mJReuWOxONx+s
|
||||
ULsl+Lqb0CVn0SrVyJ6wt4t6yTeSCafhPhAf0OXn6L60UMxiLolFAtmN35S2Ob1lZpQ1r/n0Qb5D
|
||||
oQ1zJiRVDgF8N3Q8TYfbi3DyWCy3lT1nxyBs6FT3S2GOzWRlxwKvlRP0RPJA9SjxEy0UoEnkA+M4
|
||||
cnzLMJrBGWLFEaaUb5lvpqbq/loOaU5+DFuHPxo82/OZuM8FXG3oVNZhtWpMpb/0Xu5m/LfLhHZQ
|
||||
7yuVI0MqZ7NE43imC8jH3IwGZlbPm0xkJYs7+2U48hXTsFSMqgGDvai0kLxyynKNT/waj+q1c1tz
|
||||
GjOpPBgdCSq3UKZxCSsqFIY+O6JbAWGWcV1pwqLyj5sGqCF1xb1F3varUWqrJv6cN3PrUXzijtfZ
|
||||
FshpBL3Xwr4GIPvU2N8EjrJgS1zl21rbXQMXeXc5jjFyrhpCzijSv/RQtyPSzHCFMhlME95fHglt
|
||||
pRsX+dfSQjUeHAlpWzJ5iOo79Ldnaxai6bXTcGO3fp07ri7HLEmXXPlYi8bv/qVxvNcdra6m7Rlb
|
||||
6JBTb5fd66VhFRjGArh2n7R1rDW4P5NOT9K0I183T2scYkeZ3q/VFyLb09U9ajzXBS8Kgkhc4mBS
|
||||
kYY9cy3Vy9lUnuNJH8HGIclUilwnBtjUOH0gteGOZ4c/XNrhXLSYDyxfnD8z1pDy7rYRvDolhnbe
|
||||
UMzxCZUs40s6s7UIvBnLgc0+vKuOkIXeOrDymlp+Zxra4MZLBbVrqD/jTJ597pDmnw5c4+DbyB88
|
||||
9Cg9DodYcSuMZT/114pptqc/EuTjRPvH/z5slzI3tluOEBBLqOXLOX+0I5929tO97wkvl/atCz+y
|
||||
xJrdwteW2FNW/NSmBP+f/maYtVs/bYyBC7Ox3jsYZHL05CIrBa/nS+b3bHfiYm4Ueil1YZZSgAUI
|
||||
fFZ1dxUmeA2oQRQ3RuGXNGLFV9/XbGFGPV6kfzk1TBBCd+izc7q1H+OHMJwmaBX2IQNYVAKHYepV
|
||||
SSGCe6CnbYHHETKGNe43EDvFgZr0gB/nVHPHZ80VV1ojOiI3XDvYIkl4ayo4bxQIgrFXWTvBI0nH
|
||||
VElWMuw2aLUWCRHHf8ymVCHjFlJnOSojfevCYyyyZDH0IcvHhrsnQ5O1OsWzONuVVKIxSxiFZ/tR
|
||||
fKDAf6xFTnw4O9Qig2VCfW2hJQrmMOuHW0W3dLQmCMO2ccdUd/xyfflH/olTiHZVdGwb8nIwRzSE
|
||||
J15jFlOJuBZBZ4CiyHyd2IFylFlB+HgHhYabhWOGwYO1ZH/Og1dtQlFMk352CGRSIFTapnWQEUtN
|
||||
l4zv8S0aaCFDyGCBqDUxZYpxGHX01y/JuH1xhn7TOCnNCI4eKDs5WGX4R425F4vF1o3BJ4vO0otq
|
||||
I3rimI7jJY1jISqnBxknCIvruF83mF5wN4X7qGLIhR8A2Vg0yFERSIXn9Vv3GHy3Vj/WIkKddlYi
|
||||
yIMv2I/VMjTLpW7pt05SWIZR0RPyxpB4SIUM9lBPGBl0GC7oSEEwRYLe4pJpZY2P0zbI1n+Oc44w
|
||||
qY3PUnmF0ixjVpDD/mJ9wpOBGTVgXlaCaZiPcIWK5NiKBIiPdGaQ0TWGvAiG7nMchdZb7Vgf8zNi
|
||||
MuMyzRdy/lePe9iC4TRx7WhhOQI/QiSVNAmAa2lT/piFbuh7ofJoYSZzrSZ1bvmWw3eN2nKUPVky
|
||||
uPN5/VRfohRd0VYZoqhKIlU6TXYhJxmPUIloAwc1bPmHEpaZYZORHNlXUJM07hATwHR8MJYqkwWR
|
||||
WaIezFhxSFlc8/Fq82hEnpeRozg3ULhhr9lAGtVEkCg5ZNRuuVleBPaZadhG0ZgkyPmDOTOKzViM
|
||||
YgOcpukKqQcbjAWS0IleQ2ROjdh6A+md1qWdBRSX7iSYgFRTtRmBpJioieXJiHfJiMGIR9fJOn8I
|
||||
MSfXYhspn4ooSa2mSAj4n+8Bmg03fBJZoPOJgsVZRxu1oOMRPXYYjdqjihFaEoZpXBREanuJoRI6
|
||||
cibFinq4ngUKh/wQd/H5ofYCZ0HJXR62opZFaAT0iFIZo4DIiUojkjeqKiuoZirKo5Y1a7AWckGa
|
||||
BkuYoD5lpDK6eUs6CkDqpETwl1EqpfhJpVeKpVl6EgUAADs=
|
||||
|
||||
--BOUNDARY--
|
||||
|
||||
--OUTER--
|
|
@ -1,23 +0,0 @@
|
|||
Return-Path: <bbb@zzz.org>
|
||||
Delivered-To: bbb@zzz.org
|
||||
Received: by mail.zzz.org (Postfix, from userid 889)
|
||||
id 27CEAD38CC; Fri, 4 May 2001 14:05:44 -0400 (EDT)
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text; charset=us-ascii
|
||||
Content-Transfer-Encoding: 7bit
|
||||
Message-ID: <15090.61304.110929.45684@aaa.zzz.org>
|
||||
From: bbb@ddd.com (John X. Doe)
|
||||
To: bbb@zzz.org
|
||||
Subject: This is a test message
|
||||
Date: Fri, 4 May 2001 14:05:44 -0400
|
||||
|
||||
|
||||
Hi,
|
||||
|
||||
I'm sorry but I'm using a drainbread ISP, which although big and
|
||||
wealthy can't seem to generate standard compliant email. :(
|
||||
|
||||
This message has a Content-Type: header with no subtype. I hope you
|
||||
can still read it.
|
||||
|
||||
-Me
|
|
@ -1,52 +0,0 @@
|
|||
Return-Path: <xx@xx.dk>
|
||||
Received: from fepD.post.tele.dk (195.41.46.149) by mail.groupcare.dk (LSMTP for Windows NT v1.1b) with SMTP id <0.0014F8A2@mail.groupcare.dk>; Mon, 30 Apr 2001 12:17:50 +0200
|
||||
User-Agent: Microsoft-Outlook-Express-Macintosh-Edition/5.02.2106
|
||||
Subject: XX
|
||||
From: xx@xx.dk
|
||||
To: XX
|
||||
Message-ID: <xxxx>
|
||||
Mime-version: 1.0
|
||||
Content-type: multipart/mixed;
|
||||
boundary="MS_Mac_OE_3071477847_720252_MIME_Part"
|
||||
|
||||
> Denne meddelelse er i MIME-format. Da dit postl¾sningsprogram ikke forstŒr dette format, kan del af eller hele meddelelsen v¾re ul¾selig.
|
||||
|
||||
--MS_Mac_OE_3071477847_720252_MIME_Part
|
||||
Content-type: multipart/alternative;
|
||||
boundary="MS_Mac_OE_3071477847_720252_MIME_Part"
|
||||
|
||||
|
||||
--MS_Mac_OE_3071477847_720252_MIME_Part
|
||||
Content-type: text/plain; charset="ISO-8859-1"
|
||||
Content-transfer-encoding: quoted-printable
|
||||
|
||||
Some removed test.
|
||||
|
||||
--MS_Mac_OE_3071477847_720252_MIME_Part
|
||||
Content-type: text/html; charset="ISO-8859-1"
|
||||
Content-transfer-encoding: quoted-printable
|
||||
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>Some removed HTML</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
Some removed text.
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
||||
|
||||
--MS_Mac_OE_3071477847_720252_MIME_Part--
|
||||
|
||||
|
||||
--MS_Mac_OE_3071477847_720252_MIME_Part
|
||||
Content-type: image/gif; name="xx.gif";
|
||||
x-mac-creator="6F676C65";
|
||||
x-mac-type="47494666"
|
||||
Content-disposition: attachment
|
||||
Content-transfer-encoding: base64
|
||||
|
||||
Some removed base64 encoded chars.
|
||||
|
||||
--MS_Mac_OE_3071477847_720252_MIME_Part--
|
||||
|
|
@ -1,123 +0,0 @@
|
|||
Return-Path: <>
|
||||
Delivered-To: scr-admin@socal-raves.org
|
||||
Received: from cougar.noc.ucla.edu (cougar.noc.ucla.edu [169.232.10.18])
|
||||
by babylon.socal-raves.org (Postfix) with ESMTP id CCC2C51B84
|
||||
for <scr-admin@socal-raves.org>; Sun, 23 Sep 2001 20:13:54 -0700 (PDT)
|
||||
Received: from sims-ms-daemon by cougar.noc.ucla.edu
|
||||
(Sun Internet Mail Server sims.3.5.2000.03.23.18.03.p10)
|
||||
id <0GK500B01D0B8Y@cougar.noc.ucla.edu> for scr-admin@socal-raves.org; Sun,
|
||||
23 Sep 2001 20:14:35 -0700 (PDT)
|
||||
Received: from cougar.noc.ucla.edu
|
||||
(Sun Internet Mail Server sims.3.5.2000.03.23.18.03.p10)
|
||||
id <0GK500B01D0B8X@cougar.noc.ucla.edu>; Sun, 23 Sep 2001 20:14:35 -0700 (PDT)
|
||||
Date: Sun, 23 Sep 2001 20:14:35 -0700 (PDT)
|
||||
From: Internet Mail Delivery <postmaster@ucla.edu>
|
||||
Subject: Delivery Notification: Delivery has failed
|
||||
To: scr-admin@socal-raves.org
|
||||
Message-id: <0GK500B04D0B8X@cougar.noc.ucla.edu>
|
||||
MIME-version: 1.0
|
||||
Sender: scr-owner@socal-raves.org
|
||||
Errors-To: scr-owner@socal-raves.org
|
||||
X-BeenThere: scr@socal-raves.org
|
||||
X-Mailman-Version: 2.1a3
|
||||
Precedence: bulk
|
||||
List-Help: <mailto:scr-request@socal-raves.org?subject=help>
|
||||
List-Post: <mailto:scr@socal-raves.org>
|
||||
List-Subscribe: <http://socal-raves.org/mailman/listinfo/scr>,
|
||||
<mailto:scr-request@socal-raves.org?subject=subscribe>
|
||||
List-Id: SoCal-Raves <scr.socal-raves.org>
|
||||
List-Unsubscribe: <http://socal-raves.org/mailman/listinfo/scr>,
|
||||
<mailto:scr-request@socal-raves.org?subject=unsubscribe>
|
||||
List-Archive: <http://socal-raves.org/mailman/private/scr/>
|
||||
Content-Type: multipart/report; boundary="Boundary_(ID_PGS2F2a+z+/jL7hupKgRhA)"
|
||||
|
||||
|
||||
--Boundary_(ID_PGS2F2a+z+/jL7hupKgRhA)
|
||||
Content-type: text/plain; charset=ISO-8859-1
|
||||
|
||||
This report relates to a message you sent with the following header fields:
|
||||
|
||||
Message-id: <002001c144a6$8752e060$56104586@oxy.edu>
|
||||
Date: Sun, 23 Sep 2001 20:10:55 -0700
|
||||
From: "Ian T. Henry" <henryi@oxy.edu>
|
||||
To: SoCal Raves <scr@socal-raves.org>
|
||||
Subject: [scr] yeah for Ians!!
|
||||
|
||||
Your message cannot be delivered to the following recipients:
|
||||
|
||||
Recipient address: jangel1@cougar.noc.ucla.edu
|
||||
Reason: recipient reached disk quota
|
||||
|
||||
|
||||
--Boundary_(ID_PGS2F2a+z+/jL7hupKgRhA)
|
||||
Content-type: message/DELIVERY-STATUS
|
||||
|
||||
Original-envelope-id: 0GK500B4HD0888@cougar.noc.ucla.edu
|
||||
Reporting-MTA: dns; cougar.noc.ucla.edu
|
||||
|
||||
Action: failed
|
||||
Status: 5.0.0 (recipient reached disk quota)
|
||||
Original-recipient: rfc822;jangel1@cougar.noc.ucla.edu
|
||||
Final-recipient: rfc822;jangel1@cougar.noc.ucla.edu
|
||||
|
||||
--Boundary_(ID_PGS2F2a+z+/jL7hupKgRhA)
|
||||
Content-type: MESSAGE/RFC822
|
||||
|
||||
Return-path: scr-admin@socal-raves.org
|
||||
Received: from sims-ms-daemon by cougar.noc.ucla.edu
|
||||
(Sun Internet Mail Server sims.3.5.2000.03.23.18.03.p10)
|
||||
id <0GK500B01D0B8X@cougar.noc.ucla.edu>; Sun, 23 Sep 2001 20:14:35 -0700 (PDT)
|
||||
Received: from panther.noc.ucla.edu by cougar.noc.ucla.edu
|
||||
(Sun Internet Mail Server sims.3.5.2000.03.23.18.03.p10)
|
||||
with ESMTP id <0GK500B4GD0888@cougar.noc.ucla.edu> for jangel1@sims-ms-daemon;
|
||||
Sun, 23 Sep 2001 20:14:33 -0700 (PDT)
|
||||
Received: from babylon.socal-raves.org
|
||||
(ip-209-85-222-117.dreamhost.com [209.85.222.117])
|
||||
by panther.noc.ucla.edu (8.9.1a/8.9.1) with ESMTP id UAA09793 for
|
||||
<jangel1@ucla.edu>; Sun, 23 Sep 2001 20:14:32 -0700 (PDT)
|
||||
Received: from babylon (localhost [127.0.0.1]) by babylon.socal-raves.org
|
||||
(Postfix) with ESMTP id D3B2951B70; Sun, 23 Sep 2001 20:13:47 -0700 (PDT)
|
||||
Received: by babylon.socal-raves.org (Postfix, from userid 60001)
|
||||
id A611F51B82; Sun, 23 Sep 2001 20:13:46 -0700 (PDT)
|
||||
Received: from tiger.cc.oxy.edu (tiger.cc.oxy.edu [134.69.3.112])
|
||||
by babylon.socal-raves.org (Postfix) with ESMTP id ADA7351B70 for
|
||||
<scr@socal-raves.org>; Sun, 23 Sep 2001 20:13:44 -0700 (PDT)
|
||||
Received: from ent (n16h86.dhcp.oxy.edu [134.69.16.86])
|
||||
by tiger.cc.oxy.edu (8.8.8/8.8.8) with SMTP id UAA08100 for
|
||||
<scr@socal-raves.org>; Sun, 23 Sep 2001 20:14:24 -0700 (PDT)
|
||||
Date: Sun, 23 Sep 2001 20:10:55 -0700
|
||||
From: "Ian T. Henry" <henryi@oxy.edu>
|
||||
Subject: [scr] yeah for Ians!!
|
||||
Sender: scr-admin@socal-raves.org
|
||||
To: SoCal Raves <scr@socal-raves.org>
|
||||
Errors-to: scr-admin@socal-raves.org
|
||||
Message-id: <002001c144a6$8752e060$56104586@oxy.edu>
|
||||
MIME-version: 1.0
|
||||
X-Mailer: Microsoft Outlook Express 5.50.4522.1200
|
||||
Content-type: text/plain; charset=us-ascii
|
||||
Precedence: bulk
|
||||
Delivered-to: scr-post@babylon.socal-raves.org
|
||||
Delivered-to: scr@socal-raves.org
|
||||
X-Converted-To-Plain-Text: from multipart/alternative by demime 0.98e
|
||||
X-Converted-To-Plain-Text: Alternative section used was text/plain
|
||||
X-BeenThere: scr@socal-raves.org
|
||||
X-Mailman-Version: 2.1a3
|
||||
List-Help: <mailto:scr-request@socal-raves.org?subject=help>
|
||||
List-Post: <mailto:scr@socal-raves.org>
|
||||
List-Subscribe: <http://socal-raves.org/mailman/listinfo/scr>,
|
||||
<mailto:scr-request@socal-raves.org?subject=subscribe>
|
||||
List-Id: SoCal-Raves <scr.socal-raves.org>
|
||||
List-Unsubscribe: <http://socal-raves.org/mailman/listinfo/scr>,
|
||||
<mailto:scr-request@socal-raves.org?subject=unsubscribe>
|
||||
List-Archive: <http://socal-raves.org/mailman/private/scr/>
|
||||
|
||||
I always love to find more Ian's that are over 3 years old!!
|
||||
|
||||
Ian
|
||||
_______________________________________________
|
||||
For event info, list questions, or to unsubscribe, see http://www.socal-raves.org/
|
||||
|
||||
|
||||
|
||||
--Boundary_(ID_PGS2F2a+z+/jL7hupKgRhA)--
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
MIME-Version: 1.0
|
||||
From: Barry <barry@digicool.com>
|
||||
To: Dingus Lovers <cravindogs@cravindogs.com>
|
||||
Subject: Here is your dingus fish
|
||||
Date: Fri, 20 Apr 2001 19:35:02 -0400
|
||||
Content-Type: multipart/mixed; boundary="BOUNDARY"
|
||||
|
||||
Hi there,
|
||||
|
||||
This is the dingus fish.
|
||||
|
||||
[Non-text (image/gif) part of message omitted, filename dingusfish.gif]
|
|
@ -1,6 +0,0 @@
|
|||
Content-Type: text/plain; charset="us-ascii"
|
||||
MIME-Version: 1.0
|
||||
Content-Transfer-Encoding: 7bit
|
||||
X-Foobar-Spoink-Defrobnit: wasnipoop; giraffes="very-long-necked-animals";
|
||||
spooge="yummy"; hippos="gargantuan"; marshmallows="gooey"
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
Send Ppp mailing list submissions to
|
||||
ppp@zzz.org
|
||||
|
||||
To subscribe or unsubscribe via the World Wide Web, visit
|
||||
http://www.zzz.org/mailman/listinfo/ppp
|
||||
or, via email, send a message with subject or body 'help' to
|
||||
ppp-request@zzz.org
|
||||
|
||||
You can reach the person managing the list at
|
||||
ppp-admin@zzz.org
|
||||
|
||||
When replying, please edit your Subject line so it is more specific
|
||||
than "Re: Contents of Ppp digest..."
|
||||
|
||||
Today's Topics:
|
||||
|
||||
1. testing #1 (Barry A. Warsaw)
|
||||
2. testing #2 (Barry A. Warsaw)
|
||||
3. testing #3 (Barry A. Warsaw)
|
||||
4. testing #4 (Barry A. Warsaw)
|
||||
5. testing #5 (Barry A. Warsaw)
|
||||
|
||||
hello
|
||||
|
||||
|
||||
hello
|
||||
|
||||
|
||||
hello
|
||||
|
||||
|
||||
hello
|
||||
|
||||
|
||||
hello
|
||||
|
||||
|
||||
|
||||
_______________________________________________
|
||||
Ppp mailing list
|
||||
Ppp@zzz.org
|
||||
http://www.zzz.org/mailman/listinfo/ppp
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
Return-Path: <bbb@zzz.org>
|
||||
Delivered-To: bbb@zzz.org
|
||||
Received: by mail.zzz.org (Postfix, from userid 889)
|
||||
id 27CEAD38CC; Fri, 4 May 2001 14:05:44 -0400 (EDT)
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=us-ascii
|
||||
Content-Transfer-Encoding: 7bit
|
||||
Message-ID: <15090.61304.110929.45684@aaa.zzz.org>
|
||||
From: bbb@ddd.com (John X. Doe)
|
||||
To: bbb@zzz.org
|
||||
Cc: ccc@zzz.org
|
||||
CC: ddd@zzz.org
|
||||
cc: eee@zzz.org
|
||||
Subject: This is a test message
|
||||
Date: Fri, 4 May 2001 14:05:44 -0400
|
||||
|
||||
|
||||
Hi,
|
||||
|
||||
Do you like this message?
|
||||
|
||||
-Me
|
|
@ -1,20 +0,0 @@
|
|||
From: aperson@dom.ain
|
||||
To: bperson@dom.ain
|
||||
Subject: Test
|
||||
Content-Type: multipart/mixed; boundary="BOUNDARY"
|
||||
|
||||
MIME message
|
||||
--BOUNDARY
|
||||
Content-Type: text/plain; charset="us-ascii"
|
||||
MIME-Version: 1.0
|
||||
Content-Transfer-Encoding: 7bit
|
||||
|
||||
One
|
||||
--BOUNDARY
|
||||
Content-Type: text/plain; charset="us-ascii"
|
||||
MIME-Version: 1.0
|
||||
Content-Transfer-Encoding: 7bit
|
||||
|
||||
Two
|
||||
--BOUNDARY--
|
||||
End of MIME message
|
|
@ -1,46 +0,0 @@
|
|||
Mime-Version: 1.0
|
||||
Message-Id: <a05001902b7f1c33773e9@[134.84.183.138]>
|
||||
Date: Tue, 16 Oct 2001 13:59:25 +0300
|
||||
To: a@example.com
|
||||
From: b@example.com
|
||||
Content-Type: multipart/mixed; boundary="============_-1208892523==_============"
|
||||
|
||||
--============_-1208892523==_============
|
||||
Content-Type: text/plain; charset="us-ascii" ; format="flowed"
|
||||
|
||||
Text text text.
|
||||
--============_-1208892523==_============
|
||||
Content-Id: <a05001902b7f1c33773e9@[134.84.183.138].0.0>
|
||||
Content-Type: image/jpeg; name="wibble.JPG"
|
||||
; x-mac-type="4A504547"
|
||||
; x-mac-creator="474B4F4E"
|
||||
Content-Disposition: attachment; filename="wibble.JPG"
|
||||
Content-Transfer-Encoding: base64
|
||||
|
||||
/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
|
||||
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAALCAXABIEBAREA
|
||||
g6bCjjw/pIZSjO6FWFpldjySOmCNrO7DBZibUXhTwtCixw+GtAijVdqxxaPp0aKvmGXa
|
||||
qrbBQvms0mAMeYS/3iTV1dG0hHaRNK01XblnWxtVdjkHLMIgTyqnk9VB7CrP2KzIINpa
|
||||
4O7I+zxYO9WV8jZg71Zlb+8rMDkEirAVQFAUAKAFAAAUAYAUDgADgY6DjpRtXj5RxjHA
|
||||
4wQRj0wQCMdCAewpaKKK/9k=
|
||||
--============_-1208892523==_============
|
||||
Content-Id: <a05001902b7f1c33773e9@[134.84.183.138].0.1>
|
||||
Content-Type: image/jpeg; name="wibble2.JPG"
|
||||
; x-mac-type="4A504547"
|
||||
; x-mac-creator="474B4F4E"
|
||||
Content-Disposition: attachment; filename="wibble2.JPG"
|
||||
Content-Transfer-Encoding: base64
|
||||
|
||||
/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB
|
||||
AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAALCAXABJ0BAREA
|
||||
/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQA
|
||||
W6NFJJBEkU10kKGTcWMDwxuU+0JHvk8qAtOpNwqSR0n8c3BlDyXHlqsUltHEiTvdXLxR
|
||||
7vMiGDNJAJWkAMk8ZkCFp5G2oo5W++INrbQtNfTQxJAuXlupz9oS4d5Y1W+E2XlWZJJE
|
||||
Y7LWYQxTLE1zuMbfBPxw8X2fibVdIbSbI6nLZxX635t9TjtYreWR7WGKJTLJFFKSlozO
|
||||
0ShxIXM43uC3/9k=
|
||||
--============_-1208892523==_============
|
||||
Content-Type: text/plain; charset="us-ascii" ; format="flowed"
|
||||
|
||||
Text text text.
|
||||
--============_-1208892523==_============--
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
From: aperson@dom.ain
|
||||
Content-Type: multipart/mixed; boundary="BOUNDARY"
|
||||
|
||||
--BOUNDARY
|
||||
Content-Type: text/plain
|
||||
|
||||
A message part
|
||||
--BOUNDARY--
|
|
@ -1,10 +0,0 @@
|
|||
Content-Type: multipart/mixed; boundary="BOUNDARY"
|
||||
MIME-Version: 1.0
|
||||
Subject: A subject
|
||||
To: aperson@dom.ain
|
||||
From: bperson@dom.ain
|
||||
|
||||
--BOUNDARY
|
||||
|
||||
|
||||
--BOUNDARY--
|
|
@ -1,117 +0,0 @@
|
|||
From MAILER-DAEMON Fri Apr 06 16:46:09 2001
|
||||
Received: from [204.245.199.98] (helo=zinfandel.lacita.com)
|
||||
by www.linux.org.uk with esmtp (Exim 3.13 #1)
|
||||
id 14lYR6-0008Iv-00
|
||||
for linuxuser-admin@www.linux.org.uk; Fri, 06 Apr 2001 16:46:09 +0100
|
||||
Received: from localhost (localhost) by zinfandel.lacita.com (8.7.3/8.6.10-MT4.00) with internal id JAB03225; Fri, 6 Apr 2001 09:23:06 -0800 (GMT-0800)
|
||||
Date: Fri, 6 Apr 2001 09:23:06 -0800 (GMT-0800)
|
||||
From: Mail Delivery Subsystem <MAILER-DAEMON@zinfandel.lacita.com>
|
||||
Subject: Returned mail: Too many hops 19 (17 max): from <linuxuser-admin@www.linux.org.uk> via [199.164.235.226], to <scoffman@wellpartner.com>
|
||||
Message-Id: <200104061723.JAB03225@zinfandel.lacita.com>
|
||||
To: <linuxuser-admin@www.linux.org.uk>
|
||||
To: postmaster@zinfandel.lacita.com
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/report; report-type=delivery-status;
|
||||
bo
|
||||
Auto-Submitted: auto-generated (failure)
|
||||
|
||||
This is a MIME-encapsulated message
|
||||
|
||||
--JAB03225.986577786/zinfandel.lacita.com
|
||||
|
||||
The original message was received at Fri, 6 Apr 2001 09:23:03 -0800 (GMT-0800)
|
||||
from [199.164.235.226]
|
||||
|
||||
----- The following addresses have delivery notifications -----
|
||||
<scoffman@wellpartner.com> (unrecoverable error)
|
||||
|
||||
----- Transcript of session follows -----
|
||||
554 Too many hops 19 (17 max): from <linuxuser-admin@www.linux.org.uk> via [199.164.235.226], to <scoffman@wellpartner.com>
|
||||
|
||||
--JAB03225.986577786/zinfandel.lacita.com
|
||||
Content-Type: message/delivery-status
|
||||
|
||||
Reporting-MTA: dns; zinfandel.lacita.com
|
||||
Received-From-MTA: dns; [199.164.235.226]
|
||||
Arrival-Date: Fri, 6 Apr 2001 09:23:03 -0800 (GMT-0800)
|
||||
|
||||
Final-Recipient: rfc822; scoffman@wellpartner.com
|
||||
Action: failed
|
||||
Status: 5.4.6
|
||||
Last-Attempt-Date: Fri, 6 Apr 2001 09:23:06 -0800 (GMT-0800)
|
||||
|
||||
--JAB03225.986577786/zinfandel.lacita.com
|
||||
Content-Type: text/rfc822-headers
|
||||
|
||||
Return-Path: linuxuser-admin@www.linux.org.uk
|
||||
Received: from ns1.wellpartner.net ([199.164.235.226]) by zinfandel.lacita.com (8.7.3/8.6.10-MT4.00) with ESMTP id JAA03225 for <scoffman@wellpartner.com>; Fri, 6 Apr 2001 09:23:03 -0800 (GMT-0800)
|
||||
Received: from zinfandel.lacita.com ([204.245.199.98])
|
||||
by
|
||||
fo
|
||||
Received: from ns1.wellpartner.net ([199.164.235.226]) by zinfandel.lacita.com (8.7.3/8.6.10-MT4.00) with ESMTP id JAA03221 for <scoffman@wellpartner.com>; Fri, 6 Apr 2001 09:22:18 -0800 (GMT-0800)
|
||||
Received: from zinfandel.lacita.com ([204.245.199.98])
|
||||
by
|
||||
fo
|
||||
Received: from ns1.wellpartner.net ([199.164.235.226]) by zinfandel.lacita.com (8.7.3/8.6.10-MT4.00) with ESMTP id JAA03217 for <scoffman@wellpartner.com>; Fri, 6 Apr 2001 09:21:37 -0800 (GMT-0800)
|
||||
Received: from zinfandel.lacita.com ([204.245.199.98])
|
||||
by
|
||||
fo
|
||||
Received: from ns1.wellpartner.net ([199.164.235.226]) by zinfandel.lacita.com (8.7.3/8.6.10-MT4.00) with ESMTP id JAA03213 for <scoffman@wellpartner.com>; Fri, 6 Apr 2001 09:20:56 -0800 (GMT-0800)
|
||||
Received: from zinfandel.lacita.com ([204.245.199.98])
|
||||
by
|
||||
fo
|
||||
Received: from ns1.wellpartner.net ([199.164.235.226]) by zinfandel.lacita.com (8.7.3/8.6.10-MT4.00) with ESMTP id JAA03209 for <scoffman@wellpartner.com>; Fri, 6 Apr 2001 09:20:15 -0800 (GMT-0800)
|
||||
Received: from zinfandel.lacita.com ([204.245.199.98])
|
||||
by
|
||||
fo
|
||||
Received: from ns1.wellpartner.net ([199.164.235.226]) by zinfandel.lacita.com (8.7.3/8.6.10-MT4.00) with ESMTP id JAA03205 for <scoffman@wellpartner.com>; Fri, 6 Apr 2001 09:19:33 -0800 (GMT-0800)
|
||||
Received: from zinfandel.lacita.com ([204.245.199.98])
|
||||
by
|
||||
fo
|
||||
Received: from ns1.wellpartner.net ([199.164.235.226]) by zinfandel.lacita.com (8.7.3/8.6.10-MT4.00) with ESMTP id JAA03201 for <scoffman@wellpartner.com>; Fri, 6 Apr 2001 09:18:52 -0800 (GMT-0800)
|
||||
Received: from zinfandel.lacita.com ([204.245.199.98])
|
||||
by
|
||||
fo
|
||||
Received: from ns1.wellpartner.net ([199.164.235.226]) by zinfandel.lacita.com (8.7.3/8.6.10-MT4.00) with ESMTP id JAA03197 for <scoffman@wellpartner.com>; Fri, 6 Apr 2001 09:17:54 -0800 (GMT-0800)
|
||||
Received: from www.linux.org.uk (parcelfarce.linux.theplanet.co.uk [195.92.249.252])
|
||||
by
|
||||
fo
|
||||
Received: from localhost.localdomain
|
||||
([
|
||||
by
|
||||
id
|
||||
Received: from [212.1.130.11] (helo=s1.uklinux.net ident=root)
|
||||
by
|
||||
id
|
||||
fo
|
||||
Received: from server (ppp-2-22.cvx4.telinco.net [212.1.149.22])
|
||||
by
|
||||
fo
|
||||
From: Daniel James <daniel@linuxuser.co.uk>
|
||||
Organization: LinuxUser
|
||||
To: linuxuser@www.linux.org.uk
|
||||
X-Mailer: KMail [version 1.1.99]
|
||||
Content-Type: text/plain;
|
||||
c
|
||||
MIME-Version: 1.0
|
||||
Message-Id: <01040616033903.00962@server>
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Subject: [LinuxUser] bulletin no. 45
|
||||
Sender: linuxuser-admin@www.linux.org.uk
|
||||
Errors-To: linuxuser-admin@www.linux.org.uk
|
||||
X-BeenThere: linuxuser@www.linux.org.uk
|
||||
X-Mailman-Version: 2.0.3
|
||||
Precedence: bulk
|
||||
List-Help: <mailto:linuxuser-request@www.linux.org.uk?subject=help>
|
||||
List-Post: <mailto:linuxuser@www.linux.org.uk>
|
||||
List-Subscribe: <http://www.linux.org.uk/mailman/listinfo/linuxuser>,
|
||||
<m
|
||||
List-Id: bulletins from LinuxUser magazine <linuxuser.www.linux.org.uk>
|
||||
List-Unsubscribe: <http://www.linux.org.uk/mailman/listinfo/linuxuser>,
|
||||
<m
|
||||
List-Archive: <http://www.linux.org.uk/pipermail/linuxuser/>
|
||||
Date: Fri, 6 Apr 2001 16:03:39 +0100
|
||||
|
||||
--JAB03225.986577786/zinfandel.lacita.com--
|
||||
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
Received: from xcar [192.168.0.2] by jeeves.wooster.local
|
||||
(SMTPD32-7.07 EVAL) id AFF92F0214; Sun, 12 May 2002 08:55:37 +0100
|
||||
Date: Sun, 12 May 2002 08:56:15 +0100
|
||||
From: Father Time <father.time@xcar.wooster.local>
|
||||
To: timbo@jeeves.wooster.local
|
||||
Subject: IMAP file test
|
||||
Message-ID: <6df65d354b.father.time@rpc.wooster.local>
|
||||
X-Organization: Home
|
||||
User-Agent: Messenger-Pro/2.50a (MsgServe/1.50) (RISC-OS/4.02) POPstar/2.03
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/mixed; boundary="1618492860--2051301190--113853680"
|
||||
Status: R
|
||||
X-UIDL: 319998302
|
||||
|
||||
This message is in MIME format which your mailer apparently does not support.
|
||||
You either require a newer version of your software which supports MIME, or
|
||||
a separate MIME decoding utility. Alternatively, ask the sender of this
|
||||
message to resend it in a different format.
|
||||
|
||||
--1618492860--2051301190--113853680
|
||||
Content-Type: text/plain; charset=us-ascii
|
||||
|
||||
Simple email with attachment.
|
||||
|
||||
|
||||
--1618492860--2051301190--113853680
|
||||
Content-Type: application/riscos; name="clock.bmp,69c"; type=BMP; load=&fff69c4b; exec=&355dd4d1; access=&03
|
||||
Content-Disposition: attachment; filename="clock.bmp"
|
||||
Content-Transfer-Encoding: base64
|
||||
|
||||
Qk12AgAAAAAAAHYAAAAoAAAAIAAAACAAAAABAAQAAAAAAAAAAADXDQAA1w0AAAAAAAAA
|
||||
AAAAAAAAAAAAiAAAiAAAAIiIAIgAAACIAIgAiIgAALu7uwCIiIgAERHdACLuIgAz//8A
|
||||
zAAAAN0R3QDu7iIA////AAAAAAAAAAAAAAAAAAAAAAAAAAi3AAAAAAAAADeAAAAAAAAA
|
||||
C3ADMzMzMANwAAAAAAAAAAAHMAAAAANwAAAAAAAAAACAMAd3zPfwAwgAAAAAAAAIAwd/
|
||||
f8x/f3AwgAAAAAAAgDB0x/f3//zPAwgAAAAAAAcHfM9////8z/AwAAAAAAiwd/f3////
|
||||
////A4AAAAAAcEx/f///////zAMAAAAAiwfM9////3///8zwOAAAAAcHf3////B/////
|
||||
8DAAAAALB/f3///wd3d3//AwAAAABwTPf//wCQAAD/zAMAAAAAsEx/f///B////8wDAA
|
||||
AAAHB39////wf/////AwAAAACwf39///8H/////wMAAAAIcHfM9///B////M8DgAAAAA
|
||||
sHTH///wf///xAMAAAAACHB3f3//8H////cDgAAAAAALB3zH//D//M9wMAAAAAAAgLB0
|
||||
z39///xHAwgAAAAAAAgLB3d3RHd3cDCAAAAAAAAAgLAHd0R3cAMIAAAAAAAAgAgLcAAA
|
||||
AAMwgAgAAAAACDAAAAu7t7cwAAgDgAAAAABzcIAAAAAAAAgDMwAAAAAAN7uwgAAAAAgH
|
||||
MzMAAAAACH97tzAAAAALu3c3gAAAAAAL+7tzDABAu7f7cAAAAAAACA+3MA7EQAv/sIAA
|
||||
AAAAAAAIAAAAAAAAAIAAAAAA
|
||||
|
||||
--1618492860--2051301190--113853680--
|
|
@ -1,15 +0,0 @@
|
|||
Return-Path: <aperson@dom.ain>
|
||||
Received: by mail.dom.ain (Postfix, from userid 889)
|
||||
id B9D0AD35DB; Tue, 4 Jun 2002 21:46:59 -0400 (EDT)
|
||||
Message-ID: <15613.28051.707126.569693@dom.ain>
|
||||
Date: Tue, 4 Jun 2002 21:46:59 -0400
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=us-ascii
|
||||
Content-Transfer-Encoding: 7bit
|
||||
Subject: bug demonstration
|
||||
12345678911234567892123456789312345678941234567895123456789612345678971234567898112345678911234567892123456789112345678911234567892123456789
|
||||
more text
|
||||
From: aperson@dom.ain (Anne P. Erson)
|
||||
To: bperson@dom.ain (Barney P. Erson)
|
||||
|
||||
test
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue