Whitespace normalization.
[python/dscho.git] / Lib / bsddb / test / test_associate.py
blob7be5ba05b72e066f5f33103afc15e2bd3344c35d
1 """
2 TestCases for DB.associate.
3 """
5 import sys, os, string
6 import tempfile
7 import time
8 from pprint import pprint
10 try:
11 from threading import Thread, currentThread
12 have_threads = 1
13 except ImportError:
14 have_threads = 0
16 import unittest
17 from test_all import verbose
19 try:
20 # For Pythons w/distutils pybsddb
21 from bsddb3 import db, dbshelve
22 except ImportError:
23 # For Python 2.3
24 from bsddb import db, dbshelve
27 #----------------------------------------------------------------------
30 musicdata = {
31 1 : ("Bad English", "The Price Of Love", "Rock"),
32 2 : ("DNA featuring Suzanne Vega", "Tom's Diner", "Rock"),
33 3 : ("George Michael", "Praying For Time", "Rock"),
34 4 : ("Gloria Estefan", "Here We Are", "Rock"),
35 5 : ("Linda Ronstadt", "Don't Know Much", "Rock"),
36 6 : ("Michael Bolton", "How Am I Supposed To Live Without You", "Blues"),
37 7 : ("Paul Young", "Oh Girl", "Rock"),
38 8 : ("Paula Abdul", "Opposites Attract", "Rock"),
39 9 : ("Richard Marx", "Should've Known Better", "Rock"),
40 10: ("Rod Stewart", "Forever Young", "Rock"),
41 11: ("Roxette", "Dangerous", "Rock"),
42 12: ("Sheena Easton", "The Lover In Me", "Rock"),
43 13: ("Sinead O'Connor", "Nothing Compares 2 U", "Rock"),
44 14: ("Stevie B.", "Because I Love You", "Rock"),
45 15: ("Taylor Dayne", "Love Will Lead You Back", "Rock"),
46 16: ("The Bangles", "Eternal Flame", "Rock"),
47 17: ("Wilson Phillips", "Release Me", "Rock"),
48 18: ("Billy Joel", "Blonde Over Blue", "Rock"),
49 19: ("Billy Joel", "Famous Last Words", "Rock"),
50 20: ("Billy Joel", "Lullabye (Goodnight, My Angel)", "Rock"),
51 21: ("Billy Joel", "The River Of Dreams", "Rock"),
52 22: ("Billy Joel", "Two Thousand Years", "Rock"),
53 23: ("Janet Jackson", "Alright", "Rock"),
54 24: ("Janet Jackson", "Black Cat", "Rock"),
55 25: ("Janet Jackson", "Come Back To Me", "Rock"),
56 26: ("Janet Jackson", "Escapade", "Rock"),
57 27: ("Janet Jackson", "Love Will Never Do (Without You)", "Rock"),
58 28: ("Janet Jackson", "Miss You Much", "Rock"),
59 29: ("Janet Jackson", "Rhythm Nation", "Rock"),
60 30: ("Janet Jackson", "State Of The World", "Rock"),
61 31: ("Janet Jackson", "The Knowledge", "Rock"),
62 32: ("Spyro Gyra", "End of Romanticism", "Jazz"),
63 33: ("Spyro Gyra", "Heliopolis", "Jazz"),
64 34: ("Spyro Gyra", "Jubilee", "Jazz"),
65 35: ("Spyro Gyra", "Little Linda", "Jazz"),
66 36: ("Spyro Gyra", "Morning Dance", "Jazz"),
67 37: ("Spyro Gyra", "Song for Lorraine", "Jazz"),
68 38: ("Yes", "Owner Of A Lonely Heart", "Rock"),
69 39: ("Yes", "Rhythm Of Love", "Rock"),
70 40: ("Cusco", "Dream Catcher", "New Age"),
71 41: ("Cusco", "Geronimos Laughter", "New Age"),
72 42: ("Cusco", "Ghost Dance", "New Age"),
73 43: ("Blue Man Group", "Drumbone", "New Age"),
74 44: ("Blue Man Group", "Endless Column", "New Age"),
75 45: ("Blue Man Group", "Klein Mandelbrot", "New Age"),
76 46: ("Kenny G", "Silhouette", "Jazz"),
77 47: ("Sade", "Smooth Operator", "Jazz"),
78 48: ("David Arkenstone", "Papillon (On The Wings Of The Butterfly)",
79 "New Age"),
80 49: ("David Arkenstone", "Stepping Stars", "New Age"),
81 50: ("David Arkenstone", "Carnation Lily Lily Rose", "New Age"),
82 51: ("David Lanz", "Behind The Waterfall", "New Age"),
83 52: ("David Lanz", "Cristofori's Dream", "New Age"),
84 53: ("David Lanz", "Heartsounds", "New Age"),
85 54: ("David Lanz", "Leaves on the Seine", "New Age"),
86 99: ("unknown artist", "Unnamed song", "Unknown"),
89 #----------------------------------------------------------------------
92 class AssociateTestCase(unittest.TestCase):
93 keytype = ''
95 def setUp(self):
96 self.filename = self.__class__.__name__ + '.db'
97 homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
98 self.homeDir = homeDir
99 try: os.mkdir(homeDir)
100 except os.error: pass
101 self.env = db.DBEnv()
102 self.env.open(homeDir, db.DB_CREATE | db.DB_INIT_MPOOL |
103 db.DB_INIT_LOCK | db.DB_THREAD)
105 def tearDown(self):
106 self.closeDB()
107 self.env.close()
108 import glob
109 files = glob.glob(os.path.join(self.homeDir, '*'))
110 for file in files:
111 os.remove(file)
113 def addDataToDB(self, d):
114 for key, value in musicdata.items():
115 if type(self.keytype) == type(''):
116 key = "%02d" % key
117 d.put(key, string.join(value, '|'))
119 def createDB(self):
120 self.primary = db.DB(self.env)
121 self.primary.set_get_returns_none(2)
122 self.primary.open(self.filename, "primary", self.dbtype,
123 db.DB_CREATE | db.DB_THREAD)
125 def closeDB(self):
126 self.primary.close()
128 def getDB(self):
129 return self.primary
131 def test01_associateWithDB(self):
132 if verbose:
133 print '\n', '-=' * 30
134 print "Running %s.test01_associateWithDB..." % \
135 self.__class__.__name__
137 self.createDB()
139 secDB = db.DB(self.env)
140 secDB.set_flags(db.DB_DUP)
141 secDB.set_get_returns_none(2)
142 secDB.open(self.filename, "secondary", db.DB_BTREE,
143 db.DB_CREATE | db.DB_THREAD)
144 self.getDB().associate(secDB, self.getGenre)
146 self.addDataToDB(self.getDB())
148 self.finish_test(secDB)
151 def test02_associateAfterDB(self):
152 if verbose:
153 print '\n', '-=' * 30
154 print "Running %s.test02_associateAfterDB..." % \
155 self.__class__.__name__
157 self.createDB()
158 self.addDataToDB(self.getDB())
160 secDB = db.DB(self.env)
161 secDB.set_flags(db.DB_DUP)
162 secDB.open(self.filename, "secondary", db.DB_BTREE,
163 db.DB_CREATE | db.DB_THREAD)
165 # adding the DB_CREATE flag will cause it to index existing records
166 self.getDB().associate(secDB, self.getGenre, db.DB_CREATE)
168 self.finish_test(secDB)
171 def finish_test(self, secDB):
172 # 'Blues' should not be in the secondary database
173 vals = secDB.pget('Blues')
174 assert vals == None, vals
176 vals = secDB.pget('Unknown')
177 assert vals[0] == 99 or vals[0] == '99', vals
178 vals[1].index('Unknown')
179 vals[1].index('Unnamed')
180 vals[1].index('unknown')
182 if verbose:
183 print "Primary key traversal:"
184 c = self.getDB().cursor()
185 count = 0
186 rec = c.first()
187 while rec is not None:
188 if type(self.keytype) == type(''):
189 assert string.atoi(rec[0]) # for primary db, key is a number
190 else:
191 assert rec[0] and type(rec[0]) == type(0)
192 count = count + 1
193 if verbose:
194 print rec
195 rec = c.next()
196 assert count == len(musicdata) # all items accounted for
199 if verbose:
200 print "Secondary key traversal:"
201 c = secDB.cursor()
202 count = 0
204 # test cursor pget
205 vals = c.pget('Unknown', flags=db.DB_LAST)
206 assert vals[1] == 99 or vals[1] == '99', vals
207 assert vals[0] == 'Unknown'
208 vals[2].index('Unknown')
209 vals[2].index('Unnamed')
210 vals[2].index('unknown')
212 vals = c.pget('Unknown', data='wrong value', flags=db.DB_GET_BOTH)
213 assert vals == None, vals
215 rec = c.first()
216 assert rec[0] == "Jazz"
217 while rec is not None:
218 count = count + 1
219 if verbose:
220 print rec
221 rec = c.next()
222 # all items accounted for EXCEPT for 1 with "Blues" genre
223 assert count == len(musicdata)-1
225 def getGenre(self, priKey, priData):
226 assert type(priData) == type("")
227 if verbose:
228 print 'getGenre key: %r data: %r' % (priKey, priData)
229 genre = string.split(priData, '|')[2]
230 if genre == 'Blues':
231 return db.DB_DONOTINDEX
232 else:
233 return genre
236 #----------------------------------------------------------------------
239 class AssociateHashTestCase(AssociateTestCase):
240 dbtype = db.DB_HASH
242 class AssociateBTreeTestCase(AssociateTestCase):
243 dbtype = db.DB_BTREE
245 class AssociateRecnoTestCase(AssociateTestCase):
246 dbtype = db.DB_RECNO
247 keytype = 0
250 #----------------------------------------------------------------------
252 class ShelveAssociateTestCase(AssociateTestCase):
254 def createDB(self):
255 self.primary = dbshelve.open(self.filename,
256 dbname="primary",
257 dbenv=self.env,
258 filetype=self.dbtype)
260 def addDataToDB(self, d):
261 for key, value in musicdata.items():
262 if type(self.keytype) == type(''):
263 key = "%02d" % key
264 d.put(key, value) # save the value as is this time
267 def getGenre(self, priKey, priData):
268 assert type(priData) == type(())
269 if verbose:
270 print 'getGenre key: %r data: %r' % (priKey, priData)
271 genre = priData[2]
272 if genre == 'Blues':
273 return db.DB_DONOTINDEX
274 else:
275 return genre
278 class ShelveAssociateHashTestCase(ShelveAssociateTestCase):
279 dbtype = db.DB_HASH
281 class ShelveAssociateBTreeTestCase(ShelveAssociateTestCase):
282 dbtype = db.DB_BTREE
284 class ShelveAssociateRecnoTestCase(ShelveAssociateTestCase):
285 dbtype = db.DB_RECNO
286 keytype = 0
289 #----------------------------------------------------------------------
291 class ThreadedAssociateTestCase(AssociateTestCase):
293 def addDataToDB(self, d):
294 t1 = Thread(target = self.writer1,
295 args = (d, ))
296 t2 = Thread(target = self.writer2,
297 args = (d, ))
299 t1.start()
300 t2.start()
301 t1.join()
302 t2.join()
304 def writer1(self, d):
305 for key, value in musicdata.items():
306 if type(self.keytype) == type(''):
307 key = "%02d" % key
308 d.put(key, string.join(value, '|'))
310 def writer2(self, d):
311 for x in range(100, 600):
312 key = 'z%2d' % x
313 value = [key] * 4
314 d.put(key, string.join(value, '|'))
317 class ThreadedAssociateHashTestCase(ShelveAssociateTestCase):
318 dbtype = db.DB_HASH
320 class ThreadedAssociateBTreeTestCase(ShelveAssociateTestCase):
321 dbtype = db.DB_BTREE
323 class ThreadedAssociateRecnoTestCase(ShelveAssociateTestCase):
324 dbtype = db.DB_RECNO
325 keytype = 0
328 #----------------------------------------------------------------------
330 def test_suite():
331 suite = unittest.TestSuite()
333 if db.version() >= (3, 3, 11):
334 suite.addTest(unittest.makeSuite(AssociateHashTestCase))
335 suite.addTest(unittest.makeSuite(AssociateBTreeTestCase))
336 suite.addTest(unittest.makeSuite(AssociateRecnoTestCase))
338 suite.addTest(unittest.makeSuite(ShelveAssociateHashTestCase))
339 suite.addTest(unittest.makeSuite(ShelveAssociateBTreeTestCase))
340 suite.addTest(unittest.makeSuite(ShelveAssociateRecnoTestCase))
342 if have_threads:
343 suite.addTest(unittest.makeSuite(ThreadedAssociateHashTestCase))
344 suite.addTest(unittest.makeSuite(ThreadedAssociateBTreeTestCase))
345 suite.addTest(unittest.makeSuite(ThreadedAssociateRecnoTestCase))
347 return suite
350 if __name__ == '__main__':
351 unittest.main(defaultTest='test_suite')