2 TestCases for multi-threaded access to a DB.
8 from pprint
import pprint
11 from threading
import Thread
, currentThread
17 from test_all
import verbose
21 from bsddb
import db
, dbshelve
23 # For earlier Pythons w/distutils pybsddb
24 from bsddb3
import db
, dbshelve
27 #----------------------------------------------------------------------
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)",
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"),
88 #----------------------------------------------------------------------
91 class AssociateTestCase(unittest
.TestCase
):
95 self
.filename
= self
.__class
__.__name
__ + '.db'
96 homeDir
= os
.path
.join(os
.path
.dirname(sys
.argv
[0]), 'db_home')
97 self
.homeDir
= homeDir
98 try: os
.mkdir(homeDir
)
100 self
.env
= db
.DBEnv()
101 self
.env
.open(homeDir
, db
.DB_CREATE | db
.DB_INIT_MPOOL |
102 db
.DB_INIT_LOCK | db
.DB_THREAD
)
108 files
= glob
.glob(os
.path
.join(self
.homeDir
, '*'))
112 def addDataToDB(self
, d
):
113 for key
, value
in musicdata
.items():
114 if type(self
.keytype
) == type(''):
116 d
.put(key
, string
.join(value
, '|'))
119 self
.primary
= db
.DB(self
.env
)
120 self
.primary
.open(self
.filename
, "primary", self
.dbtype
,
121 db
.DB_CREATE | db
.DB_THREAD
)
129 def test01_associateWithDB(self
):
131 print '\n', '-=' * 30
132 print "Running %s.test01_associateWithDB..." % \
133 self
.__class
__.__name
__
137 secDB
= db
.DB(self
.env
)
138 secDB
.set_flags(db
.DB_DUP
)
139 secDB
.open(self
.filename
, "secondary", db
.DB_BTREE
,
140 db
.DB_CREATE | db
.DB_THREAD
)
141 self
.getDB().associate(secDB
, self
.getGenre
)
143 self
.addDataToDB(self
.getDB())
145 self
.finish_test(secDB
)
148 def test02_associateAfterDB(self
):
150 print '\n', '-=' * 30
151 print "Running %s.test02_associateAfterDB..." % \
152 self
.__class
__.__name
__
155 self
.addDataToDB(self
.getDB())
157 secDB
= db
.DB(self
.env
)
158 secDB
.set_flags(db
.DB_DUP
)
159 secDB
.open(self
.filename
, "secondary", db
.DB_BTREE
,
160 db
.DB_CREATE | db
.DB_THREAD
)
162 # adding the DB_CREATE flag will cause it to index existing records
163 self
.getDB().associate(secDB
, self
.getGenre
, db
.DB_CREATE
)
165 self
.finish_test(secDB
)
168 def finish_test(self
, secDB
):
170 print "Primary key traversal:"
171 c
= self
.getDB().cursor()
174 while rec
is not None:
175 if type(self
.keytype
) == type(''):
176 assert string
.atoi(rec
[0]) # for primary db, key is a number
178 assert rec
[0] and type(rec
[0]) == type(0)
183 assert count
== len(musicdata
) # all items accounted for
187 print "Secondary key traversal:"
191 assert rec
[0] == "Jazz"
192 while rec
is not None:
197 # all items accounted for EXCEPT for 1 with "Blues" genre
198 assert count
== len(musicdata
)-1
200 def getGenre(self
, priKey
, priData
):
201 assert type(priData
) == type("")
203 print 'getGenre key:', `priKey`
, 'data:', `priData`
204 genre
= string
.split(priData
, '|')[2]
206 return db
.DB_DONOTINDEX
211 #----------------------------------------------------------------------
214 class AssociateHashTestCase(AssociateTestCase
):
217 class AssociateBTreeTestCase(AssociateTestCase
):
220 class AssociateRecnoTestCase(AssociateTestCase
):
225 #----------------------------------------------------------------------
227 class ShelveAssociateTestCase(AssociateTestCase
):
230 self
.primary
= dbshelve
.open(self
.filename
,
233 filetype
=self
.dbtype
)
235 def addDataToDB(self
, d
):
236 for key
, value
in musicdata
.items():
237 if type(self
.keytype
) == type(''):
239 d
.put(key
, value
) # save the value as is this time
242 def getGenre(self
, priKey
, priData
):
243 assert type(priData
) == type(())
245 print 'getGenre key:', `priKey`
, 'data:', `priData`
248 return db
.DB_DONOTINDEX
253 class ShelveAssociateHashTestCase(ShelveAssociateTestCase
):
256 class ShelveAssociateBTreeTestCase(ShelveAssociateTestCase
):
259 class ShelveAssociateRecnoTestCase(ShelveAssociateTestCase
):
264 #----------------------------------------------------------------------
266 class ThreadedAssociateTestCase(AssociateTestCase
):
268 def addDataToDB(self
, d
):
269 t1
= Thread(target
= self
.writer1
,
271 t2
= Thread(target
= self
.writer2
,
279 def writer1(self
, d
):
280 for key
, value
in musicdata
.items():
281 if type(self
.keytype
) == type(''):
283 d
.put(key
, string
.join(value
, '|'))
285 def writer2(self
, d
):
286 for x
in range(100, 600):
289 d
.put(key
, string
.join(value
, '|'))
292 class ThreadedAssociateHashTestCase(ShelveAssociateTestCase
):
295 class ThreadedAssociateBTreeTestCase(ShelveAssociateTestCase
):
298 class ThreadedAssociateRecnoTestCase(ShelveAssociateTestCase
):
303 #----------------------------------------------------------------------
306 suite
= unittest
.TestSuite()
308 if db
.version() >= (3, 3, 11):
309 suite
.addTest(unittest
.makeSuite(AssociateHashTestCase
))
310 suite
.addTest(unittest
.makeSuite(AssociateBTreeTestCase
))
311 suite
.addTest(unittest
.makeSuite(AssociateRecnoTestCase
))
313 suite
.addTest(unittest
.makeSuite(ShelveAssociateHashTestCase
))
314 suite
.addTest(unittest
.makeSuite(ShelveAssociateBTreeTestCase
))
315 suite
.addTest(unittest
.makeSuite(ShelveAssociateRecnoTestCase
))
318 suite
.addTest(unittest
.makeSuite(ThreadedAssociateHashTestCase
))
319 suite
.addTest(unittest
.makeSuite(ThreadedAssociateBTreeTestCase
))
320 suite
.addTest(unittest
.makeSuite(ThreadedAssociateRecnoTestCase
))
325 if __name__
== '__main__':
326 unittest
.main(defaultTest
='test_suite')