0001 #!/usr/bin/env python 0002 # 0003 #----------------------------------------------------------------------- 0004 # A test suite for the table interface built on bsddb.db 0005 #----------------------------------------------------------------------- 0006 # 0007 # Copyright (C) 2000, 2001 by Autonomous Zone Industries 0008 # Copyright (C) 2002 Gregory P. Smith 0009 # 0010 # March 20, 2000 0011 # 0012 # License: This is free software. You may use this software for any 0013 # purpose including modification/redistribution, so long as 0014 # this header remains intact and that you do not claim any 0015 # rights of ownership or authorship of this software. This 0016 # software has been tested, but no warranty is expressed or 0017 # implied. 0018 # 0019 # -- Gregory P. Smith <greg@electricrain.com> 0020 # 0021 # $Id: test_dbtables.py,v 1.7 2004/02/12 17:35:08 doerwalter Exp $ 0022 0023 import sys, os, re 0024 try: 0025 import cPickle 0026 pickle = cPickle 0027 except ImportError: 0028 import pickle 0029 0030 import unittest 0031 from test_all import verbose 0032 0033 try: 0034 # For Pythons w/distutils pybsddb 0035 from bsddb3 import db, dbtables 0036 except ImportError: 0037 # For Python 2.3 0038 from bsddb import db, dbtables 0039 0040 0041 0042 #---------------------------------------------------------------------- 0043 0044 class TableDBTestCase(unittest.TestCase): 0045 db_home = 'db_home' 0046 db_name = 'test-table.db' 0047 0048 def setUp(self): 0049 homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home') 0050 self.homeDir = homeDir 0051 try: os.mkdir(homeDir) 0052 except os.error: pass 0053 self.tdb = dbtables.bsdTableDB( 0054 filename='tabletest.db', dbhome=homeDir, create=1) 0055 0056 def tearDown(self): 0057 self.tdb.close() 0058 import glob 0059 files = glob.glob(os.path.join(self.homeDir, '*')) 0060 for file in files: 0061 os.remove(file) 0062 0063 def test01(self): 0064 tabname = "test01" 0065 colname = 'cool numbers' 0066 try: 0067 self.tdb.Drop(tabname) 0068 except dbtables.TableDBError: 0069 pass 0070 self.tdb.CreateTable(tabname, [colname]) 0071 self.tdb.Insert(tabname, {colname: pickle.dumps(3.14159, 1)}) 0072 0073 if verbose: 0074 self.tdb._db_print() 0075 0076 values = self.tdb.Select( 0077 tabname, [colname], conditions={colname: None}) 0078 0079 colval = pickle.loads(values[0][colname]) 0080 assert(colval > 3.141 and colval < 3.142) 0081 0082 0083 def test02(self): 0084 tabname = "test02" 0085 col0 = 'coolness factor' 0086 col1 = 'but can it fly?' 0087 col2 = 'Species' 0088 testinfo = [ 0089 {col0: pickle.dumps(8, 1), col1: 'no', col2: 'Penguin'}, 0090 {col0: pickle.dumps(-1, 1), col1: 'no', col2: 'Turkey'}, 0091 {col0: pickle.dumps(9, 1), col1: 'yes', col2: 'SR-71A Blackbird'} 0092 ] 0093 0094 try: 0095 self.tdb.Drop(tabname) 0096 except dbtables.TableDBError: 0097 pass 0098 self.tdb.CreateTable(tabname, [col0, col1, col2]) 0099 for row in testinfo : 0100 self.tdb.Insert(tabname, row) 0101 0102 values = self.tdb.Select(tabname, [col2], 0103 conditions={col0: lambda x: pickle.loads(x) >= 8}) 0104 0105 assert len(values) == 2 0106 if values[0]['Species'] == 'Penguin' : 0107 assert values[1]['Species'] == 'SR-71A Blackbird' 0108 elif values[0]['Species'] == 'SR-71A Blackbird' : 0109 assert values[1]['Species'] == 'Penguin' 0110 else : 0111 if verbose: 0112 print "values= %r" % (values,) 0113 raise "Wrong values returned!" 0114 0115 def test03(self): 0116 tabname = "test03" 0117 try: 0118 self.tdb.Drop(tabname) 0119 except dbtables.TableDBError: 0120 pass 0121 if verbose: 0122 print '...before CreateTable...' 0123 self.tdb._db_print() 0124 self.tdb.CreateTable(tabname, ['a', 'b', 'c', 'd', 'e']) 0125 if verbose: 0126 print '...after CreateTable...' 0127 self.tdb._db_print() 0128 self.tdb.Drop(tabname) 0129 if verbose: 0130 print '...after Drop...' 0131 self.tdb._db_print() 0132 self.tdb.CreateTable(tabname, ['a', 'b', 'c', 'd', 'e']) 0133 0134 try: 0135 self.tdb.Insert(tabname, 0136 {'a': "", 0137 'e': pickle.dumps([{4:5, 6:7}, 'foo'], 1), 0138 'f': "Zero"}) 0139 assert 0 0140 except dbtables.TableDBError: 0141 pass 0142 0143 try: 0144 self.tdb.Select(tabname, [], conditions={'foo': '123'}) 0145 assert 0 0146 except dbtables.TableDBError: 0147 pass 0148 0149 self.tdb.Insert(tabname, 0150 {'a': '42', 0151 'b': "bad", 0152 'c': "meep", 0153 'e': 'Fuzzy wuzzy was a bear'}) 0154 self.tdb.Insert(tabname, 0155 {'a': '581750', 0156 'b': "good", 0157 'd': "bla", 0158 'c': "black", 0159 'e': 'fuzzy was here'}) 0160 self.tdb.Insert(tabname, 0161 {'a': '800000', 0162 'b': "good", 0163 'd': "bla", 0164 'c': "black", 0165 'e': 'Fuzzy wuzzy is a bear'}) 0166 0167 if verbose: 0168 self.tdb._db_print() 0169 0170 # this should return two rows 0171 values = self.tdb.Select(tabname, ['b', 'a', 'd'], 0172 conditions={'e': re.compile('wuzzy').search, 0173 'a': re.compile('^[0-9]+$').match}) 0174 assert len(values) == 2 0175 0176 # now lets delete one of them and try again 0177 self.tdb.Delete(tabname, conditions={'b': dbtables.ExactCond('good')}) 0178 values = self.tdb.Select( 0179 tabname, ['a', 'd', 'b'], 0180 conditions={'e': dbtables.PrefixCond('Fuzzy')}) 0181 assert len(values) == 1 0182 assert values[0]['d'] == None 0183 0184 values = self.tdb.Select(tabname, ['b'], 0185 conditions={'c': lambda c: c == 'meep'}) 0186 assert len(values) == 1 0187 assert values[0]['b'] == "bad" 0188 0189 0190 def test04_MultiCondSelect(self): 0191 tabname = "test04_MultiCondSelect" 0192 try: 0193 self.tdb.Drop(tabname) 0194 except dbtables.TableDBError: 0195 pass 0196 self.tdb.CreateTable(tabname, ['a', 'b', 'c', 'd', 'e']) 0197 0198 try: 0199 self.tdb.Insert(tabname, 0200 {'a': "", 0201 'e': pickle.dumps([{4:5, 6:7}, 'foo'], 1), 0202 'f': "Zero"}) 0203 assert 0 0204 except dbtables.TableDBError: 0205 pass 0206 0207 self.tdb.Insert(tabname, {'a': "A", 'b': "B", 'c': "C", 'd': "D", 0208 'e': "E"}) 0209 self.tdb.Insert(tabname, {'a': "-A", 'b': "-B", 'c': "-C", 'd': "-D", 0210 'e': "-E"}) 0211 self.tdb.Insert(tabname, {'a': "A-", 'b': "B-", 'c': "C-", 'd': "D-", 0212 'e': "E-"}) 0213 0214 if verbose: 0215 self.tdb._db_print() 0216 0217 # This select should return 0 rows. it is designed to test 0218 # the bug identified and fixed in sourceforge bug # 590449 0219 # (Big Thanks to "Rob Tillotson (n9mtb)" for tracking this down 0220 # and supplying a fix!! This one caused many headaches to say 0221 # the least...) 0222 values = self.tdb.Select(tabname, ['b', 'a', 'd'], 0223 conditions={'e': dbtables.ExactCond('E'), 0224 'a': dbtables.ExactCond('A'), 0225 'd': dbtables.PrefixCond('-') 0226 } ) 0227 assert len(values) == 0, values 0228 0229 0230 def test_CreateOrExtend(self): 0231 tabname = "test_CreateOrExtend" 0232 0233 self.tdb.CreateOrExtendTable( 0234 tabname, ['name', 'taste', 'filling', 'alcohol content', 'price']) 0235 try: 0236 self.tdb.Insert(tabname, 0237 {'taste': 'crap', 0238 'filling': 'no', 0239 'is it Guinness?': 'no'}) 0240 assert 0, "Insert should've failed due to bad column name" 0241 except: 0242 pass 0243 self.tdb.CreateOrExtendTable(tabname, 0244 ['name', 'taste', 'is it Guinness?']) 0245 0246 # these should both succeed as the table should contain the union of both sets of columns. 0247 self.tdb.Insert(tabname, {'taste': 'crap', 'filling': 'no', 0248 'is it Guinness?': 'no'}) 0249 self.tdb.Insert(tabname, {'taste': 'great', 'filling': 'yes', 0250 'is it Guinness?': 'yes', 0251 'name': 'Guinness'}) 0252 0253 0254 def test_CondObjs(self): 0255 tabname = "test_CondObjs" 0256 0257 self.tdb.CreateTable(tabname, ['a', 'b', 'c', 'd', 'e', 'p']) 0258 0259 self.tdb.Insert(tabname, {'a': "the letter A", 0260 'b': "the letter B", 0261 'c': "is for cookie"}) 0262 self.tdb.Insert(tabname, {'a': "is for aardvark", 0263 'e': "the letter E", 0264 'c': "is for cookie", 0265 'd': "is for dog"}) 0266 self.tdb.Insert(tabname, {'a': "the letter A", 0267 'e': "the letter E", 0268 'c': "is for cookie", 0269 'p': "is for Python"}) 0270 0271 values = self.tdb.Select( 0272 tabname, ['p', 'e'], 0273 conditions={'e': dbtables.PrefixCond('the l')}) 0274 assert len(values) == 2, values 0275 assert values[0]['e'] == values[1]['e'], values 0276 assert values[0]['p'] != values[1]['p'], values 0277 0278 values = self.tdb.Select( 0279 tabname, ['d', 'a'], 0280 conditions={'a': dbtables.LikeCond('%aardvark%')}) 0281 assert len(values) == 1, values 0282 assert values[0]['d'] == "is for dog", values 0283 assert values[0]['a'] == "is for aardvark", values 0284 0285 values = self.tdb.Select(tabname, None, 0286 {'b': dbtables.Cond(), 0287 'e':dbtables.LikeCond('%letter%'), 0288 'a':dbtables.PrefixCond('is'), 0289 'd':dbtables.ExactCond('is for dog'), 0290 'c':dbtables.PrefixCond('is for'), 0291 'p':lambda s: not s}) 0292 assert len(values) == 1, values 0293 assert values[0]['d'] == "is for dog", values 0294 assert values[0]['a'] == "is for aardvark", values 0295 0296 def test_Delete(self): 0297 tabname = "test_Delete" 0298 self.tdb.CreateTable(tabname, ['x', 'y', 'z']) 0299 0300 # prior to 2001-05-09 there was a bug where Delete() would 0301 # fail if it encountered any rows that did not have values in 0302 # every column. 0303 # Hunted and Squashed by <Donwulff> (Jukka Santala - donwulff@nic.fi) 0304 self.tdb.Insert(tabname, {'x': 'X1', 'y':'Y1'}) 0305 self.tdb.Insert(tabname, {'x': 'X2', 'y':'Y2', 'z': 'Z2'}) 0306 0307 self.tdb.Delete(tabname, conditions={'x': dbtables.PrefixCond('X')}) 0308 values = self.tdb.Select(tabname, ['y'], 0309 conditions={'x': dbtables.PrefixCond('X')}) 0310 assert len(values) == 0 0311 0312 def test_Modify(self): 0313 tabname = "test_Modify" 0314 self.tdb.CreateTable(tabname, ['Name', 'Type', 'Access']) 0315 0316 self.tdb.Insert(tabname, {'Name': 'Index to MP3 files.doc', 0317 'Type': 'Word', 'Access': '8'}) 0318 self.tdb.Insert(tabname, {'Name': 'Nifty.MP3', 'Access': '1'}) 0319 self.tdb.Insert(tabname, {'Type': 'Unknown', 'Access': '0'}) 0320 0321 def set_type(type): 0322 if type == None: 0323 return 'MP3' 0324 return type 0325 0326 def increment_access(count): 0327 return str(int(count)+1) 0328 0329 def remove_value(value): 0330 return None 0331 0332 self.tdb.Modify(tabname, 0333 conditions={'Access': dbtables.ExactCond('0')}, 0334 mappings={'Access': remove_value}) 0335 self.tdb.Modify(tabname, 0336 conditions={'Name': dbtables.LikeCond('%MP3%')}, 0337 mappings={'Type': set_type}) 0338 self.tdb.Modify(tabname, 0339 conditions={'Name': dbtables.LikeCond('%')}, 0340 mappings={'Access': increment_access}) 0341 0342 # Delete key in select conditions 0343 values = self.tdb.Select( 0344 tabname, None, 0345 conditions={'Type': dbtables.ExactCond('Unknown')}) 0346 assert len(values) == 1, values 0347 assert values[0]['Name'] == None, values 0348 assert values[0]['Access'] == None, values 0349 0350 # Modify value by select conditions 0351 values = self.tdb.Select( 0352 tabname, None, 0353 conditions={'Name': dbtables.ExactCond('Nifty.MP3')}) 0354 assert len(values) == 1, values 0355 assert values[0]['Type'] == "MP3", values 0356 assert values[0]['Access'] == "2", values 0357 0358 # Make sure change applied only to select conditions 0359 values = self.tdb.Select( 0360 tabname, None, conditions={'Name': dbtables.LikeCond('%doc%')}) 0361 assert len(values) == 1, values 0362 assert values[0]['Type'] == "Word", values 0363 assert values[0]['Access'] == "9", values 0364 0365 0366 def test_suite(): 0367 suite = unittest.TestSuite() 0368 suite.addTest(unittest.makeSuite(TableDBTestCase)) 0369 return suite 0370 0371 0372 if __name__ == '__main__': 0373 unittest.main(defaultTest='test_suite') 0374
Generated by PyXR 0.9.4