symbian-qemu-0.9.1-12/python-2.6.1/Lib/bsddb/test/test_associate.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 """
       
     2 TestCases for DB.associate.
       
     3 """
       
     4 
       
     5 import sys, os, string
       
     6 import time
       
     7 from pprint import pprint
       
     8 
       
     9 import unittest
       
    10 from test_all import db, dbshelve, test_support, verbose, have_threads, \
       
    11         get_new_environment_path
       
    12 
       
    13 
       
    14 #----------------------------------------------------------------------
       
    15 
       
    16 
       
    17 musicdata = {
       
    18 1 : ("Bad English", "The Price Of Love", "Rock"),
       
    19 2 : ("DNA featuring Suzanne Vega", "Tom's Diner", "Rock"),
       
    20 3 : ("George Michael", "Praying For Time", "Rock"),
       
    21 4 : ("Gloria Estefan", "Here We Are", "Rock"),
       
    22 5 : ("Linda Ronstadt", "Don't Know Much", "Rock"),
       
    23 6 : ("Michael Bolton", "How Am I Supposed To Live Without You", "Blues"),
       
    24 7 : ("Paul Young", "Oh Girl", "Rock"),
       
    25 8 : ("Paula Abdul", "Opposites Attract", "Rock"),
       
    26 9 : ("Richard Marx", "Should've Known Better", "Rock"),
       
    27 10: ("Rod Stewart", "Forever Young", "Rock"),
       
    28 11: ("Roxette", "Dangerous", "Rock"),
       
    29 12: ("Sheena Easton", "The Lover In Me", "Rock"),
       
    30 13: ("Sinead O'Connor", "Nothing Compares 2 U", "Rock"),
       
    31 14: ("Stevie B.", "Because I Love You", "Rock"),
       
    32 15: ("Taylor Dayne", "Love Will Lead You Back", "Rock"),
       
    33 16: ("The Bangles", "Eternal Flame", "Rock"),
       
    34 17: ("Wilson Phillips", "Release Me", "Rock"),
       
    35 18: ("Billy Joel", "Blonde Over Blue", "Rock"),
       
    36 19: ("Billy Joel", "Famous Last Words", "Rock"),
       
    37 20: ("Billy Joel", "Lullabye (Goodnight, My Angel)", "Rock"),
       
    38 21: ("Billy Joel", "The River Of Dreams", "Rock"),
       
    39 22: ("Billy Joel", "Two Thousand Years", "Rock"),
       
    40 23: ("Janet Jackson", "Alright", "Rock"),
       
    41 24: ("Janet Jackson", "Black Cat", "Rock"),
       
    42 25: ("Janet Jackson", "Come Back To Me", "Rock"),
       
    43 26: ("Janet Jackson", "Escapade", "Rock"),
       
    44 27: ("Janet Jackson", "Love Will Never Do (Without You)", "Rock"),
       
    45 28: ("Janet Jackson", "Miss You Much", "Rock"),
       
    46 29: ("Janet Jackson", "Rhythm Nation", "Rock"),
       
    47 30: ("Janet Jackson", "State Of The World", "Rock"),
       
    48 31: ("Janet Jackson", "The Knowledge", "Rock"),
       
    49 32: ("Spyro Gyra", "End of Romanticism", "Jazz"),
       
    50 33: ("Spyro Gyra", "Heliopolis", "Jazz"),
       
    51 34: ("Spyro Gyra", "Jubilee", "Jazz"),
       
    52 35: ("Spyro Gyra", "Little Linda", "Jazz"),
       
    53 36: ("Spyro Gyra", "Morning Dance", "Jazz"),
       
    54 37: ("Spyro Gyra", "Song for Lorraine", "Jazz"),
       
    55 38: ("Yes", "Owner Of A Lonely Heart", "Rock"),
       
    56 39: ("Yes", "Rhythm Of Love", "Rock"),
       
    57 40: ("Cusco", "Dream Catcher", "New Age"),
       
    58 41: ("Cusco", "Geronimos Laughter", "New Age"),
       
    59 42: ("Cusco", "Ghost Dance", "New Age"),
       
    60 43: ("Blue Man Group", "Drumbone", "New Age"),
       
    61 44: ("Blue Man Group", "Endless Column", "New Age"),
       
    62 45: ("Blue Man Group", "Klein Mandelbrot", "New Age"),
       
    63 46: ("Kenny G", "Silhouette", "Jazz"),
       
    64 47: ("Sade", "Smooth Operator", "Jazz"),
       
    65 48: ("David Arkenstone", "Papillon (On The Wings Of The Butterfly)",
       
    66      "New Age"),
       
    67 49: ("David Arkenstone", "Stepping Stars", "New Age"),
       
    68 50: ("David Arkenstone", "Carnation Lily Lily Rose", "New Age"),
       
    69 51: ("David Lanz", "Behind The Waterfall", "New Age"),
       
    70 52: ("David Lanz", "Cristofori's Dream", "New Age"),
       
    71 53: ("David Lanz", "Heartsounds", "New Age"),
       
    72 54: ("David Lanz", "Leaves on the Seine", "New Age"),
       
    73 99: ("unknown artist", "Unnamed song", "Unknown"),
       
    74 }
       
    75 
       
    76 #----------------------------------------------------------------------
       
    77 
       
    78 class AssociateErrorTestCase(unittest.TestCase):
       
    79     def setUp(self):
       
    80         self.filename = self.__class__.__name__ + '.db'
       
    81         self.homeDir = get_new_environment_path()
       
    82         self.env = db.DBEnv()
       
    83         self.env.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL)
       
    84 
       
    85     def tearDown(self):
       
    86         self.env.close()
       
    87         self.env = None
       
    88         test_support.rmtree(self.homeDir)
       
    89 
       
    90     def test00_associateDBError(self):
       
    91         if verbose:
       
    92             print '\n', '-=' * 30
       
    93             print "Running %s.test00_associateDBError..." % \
       
    94                   self.__class__.__name__
       
    95 
       
    96         dupDB = db.DB(self.env)
       
    97         dupDB.set_flags(db.DB_DUP)
       
    98         dupDB.open(self.filename, "primary", db.DB_BTREE, db.DB_CREATE)
       
    99 
       
   100         secDB = db.DB(self.env)
       
   101         secDB.open(self.filename, "secondary", db.DB_BTREE, db.DB_CREATE)
       
   102 
       
   103         # dupDB has been configured to allow duplicates, it can't
       
   104         # associate with a secondary.  Berkeley DB will return an error.
       
   105         try:
       
   106             def f(a,b): return a+b
       
   107             dupDB.associate(secDB, f)
       
   108         except db.DBError:
       
   109             # good
       
   110             secDB.close()
       
   111             dupDB.close()
       
   112         else:
       
   113             secDB.close()
       
   114             dupDB.close()
       
   115             self.fail("DBError exception was expected")
       
   116 
       
   117 
       
   118 
       
   119 #----------------------------------------------------------------------
       
   120 
       
   121 
       
   122 class AssociateTestCase(unittest.TestCase):
       
   123     keytype = ''
       
   124     envFlags = 0
       
   125     dbFlags = 0
       
   126 
       
   127     def setUp(self):
       
   128         self.filename = self.__class__.__name__ + '.db'
       
   129         self.homeDir = get_new_environment_path()
       
   130         self.env = db.DBEnv()
       
   131         self.env.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL |
       
   132                                db.DB_INIT_LOCK | db.DB_THREAD | self.envFlags)
       
   133 
       
   134     def tearDown(self):
       
   135         self.closeDB()
       
   136         self.env.close()
       
   137         self.env = None
       
   138         test_support.rmtree(self.homeDir)
       
   139 
       
   140     def addDataToDB(self, d, txn=None):
       
   141         for key, value in musicdata.items():
       
   142             if type(self.keytype) == type(''):
       
   143                 key = "%02d" % key
       
   144             d.put(key, '|'.join(value), txn=txn)
       
   145 
       
   146     def createDB(self, txn=None):
       
   147         self.cur = None
       
   148         self.secDB = None
       
   149         self.primary = db.DB(self.env)
       
   150         self.primary.set_get_returns_none(2)
       
   151         if db.version() >= (4, 1):
       
   152             self.primary.open(self.filename, "primary", self.dbtype,
       
   153                           db.DB_CREATE | db.DB_THREAD | self.dbFlags, txn=txn)
       
   154         else:
       
   155             self.primary.open(self.filename, "primary", self.dbtype,
       
   156                           db.DB_CREATE | db.DB_THREAD | self.dbFlags)
       
   157 
       
   158     def closeDB(self):
       
   159         if self.cur:
       
   160             self.cur.close()
       
   161             self.cur = None
       
   162         if self.secDB:
       
   163             self.secDB.close()
       
   164             self.secDB = None
       
   165         self.primary.close()
       
   166         self.primary = None
       
   167 
       
   168     def getDB(self):
       
   169         return self.primary
       
   170 
       
   171 
       
   172     def test01_associateWithDB(self):
       
   173         if verbose:
       
   174             print '\n', '-=' * 30
       
   175             print "Running %s.test01_associateWithDB..." % \
       
   176                   self.__class__.__name__
       
   177 
       
   178         self.createDB()
       
   179 
       
   180         self.secDB = db.DB(self.env)
       
   181         self.secDB.set_flags(db.DB_DUP)
       
   182         self.secDB.set_get_returns_none(2)
       
   183         self.secDB.open(self.filename, "secondary", db.DB_BTREE,
       
   184                    db.DB_CREATE | db.DB_THREAD | self.dbFlags)
       
   185         self.getDB().associate(self.secDB, self.getGenre)
       
   186 
       
   187         self.addDataToDB(self.getDB())
       
   188 
       
   189         self.finish_test(self.secDB)
       
   190 
       
   191 
       
   192     def test02_associateAfterDB(self):
       
   193         if verbose:
       
   194             print '\n', '-=' * 30
       
   195             print "Running %s.test02_associateAfterDB..." % \
       
   196                   self.__class__.__name__
       
   197 
       
   198         self.createDB()
       
   199         self.addDataToDB(self.getDB())
       
   200 
       
   201         self.secDB = db.DB(self.env)
       
   202         self.secDB.set_flags(db.DB_DUP)
       
   203         self.secDB.open(self.filename, "secondary", db.DB_BTREE,
       
   204                    db.DB_CREATE | db.DB_THREAD | self.dbFlags)
       
   205 
       
   206         # adding the DB_CREATE flag will cause it to index existing records
       
   207         self.getDB().associate(self.secDB, self.getGenre, db.DB_CREATE)
       
   208 
       
   209         self.finish_test(self.secDB)
       
   210 
       
   211 
       
   212     def finish_test(self, secDB, txn=None):
       
   213         # 'Blues' should not be in the secondary database
       
   214         vals = secDB.pget('Blues', txn=txn)
       
   215         self.assertEqual(vals, None, vals)
       
   216 
       
   217         vals = secDB.pget('Unknown', txn=txn)
       
   218         self.assert_(vals[0] == 99 or vals[0] == '99', vals)
       
   219         vals[1].index('Unknown')
       
   220         vals[1].index('Unnamed')
       
   221         vals[1].index('unknown')
       
   222 
       
   223         if verbose:
       
   224             print "Primary key traversal:"
       
   225         self.cur = self.getDB().cursor(txn)
       
   226         count = 0
       
   227         rec = self.cur.first()
       
   228         while rec is not None:
       
   229             if type(self.keytype) == type(''):
       
   230                 self.assert_(int(rec[0]))  # for primary db, key is a number
       
   231             else:
       
   232                 self.assert_(rec[0] and type(rec[0]) == type(0))
       
   233             count = count + 1
       
   234             if verbose:
       
   235                 print rec
       
   236             rec = getattr(self.cur, "next")()
       
   237         self.assertEqual(count, len(musicdata))  # all items accounted for
       
   238 
       
   239 
       
   240         if verbose:
       
   241             print "Secondary key traversal:"
       
   242         self.cur = secDB.cursor(txn)
       
   243         count = 0
       
   244 
       
   245         # test cursor pget
       
   246         vals = self.cur.pget('Unknown', flags=db.DB_LAST)
       
   247         self.assert_(vals[1] == 99 or vals[1] == '99', vals)
       
   248         self.assertEqual(vals[0], 'Unknown')
       
   249         vals[2].index('Unknown')
       
   250         vals[2].index('Unnamed')
       
   251         vals[2].index('unknown')
       
   252 
       
   253         vals = self.cur.pget('Unknown', data='wrong value', flags=db.DB_GET_BOTH)
       
   254         self.assertEqual(vals, None, vals)
       
   255 
       
   256         rec = self.cur.first()
       
   257         self.assertEqual(rec[0], "Jazz")
       
   258         while rec is not None:
       
   259             count = count + 1
       
   260             if verbose:
       
   261                 print rec
       
   262             rec = getattr(self.cur, "next")()
       
   263         # all items accounted for EXCEPT for 1 with "Blues" genre
       
   264         self.assertEqual(count, len(musicdata)-1)
       
   265 
       
   266         self.cur = None
       
   267 
       
   268     def getGenre(self, priKey, priData):
       
   269         self.assertEqual(type(priData), type(""))
       
   270         genre = priData.split('|')[2]
       
   271 
       
   272         if verbose:
       
   273             print 'getGenre key: %r data: %r' % (priKey, priData)
       
   274 
       
   275         if genre == 'Blues':
       
   276             return db.DB_DONOTINDEX
       
   277         else:
       
   278             return genre
       
   279 
       
   280 
       
   281 #----------------------------------------------------------------------
       
   282 
       
   283 
       
   284 class AssociateHashTestCase(AssociateTestCase):
       
   285     dbtype = db.DB_HASH
       
   286 
       
   287 class AssociateBTreeTestCase(AssociateTestCase):
       
   288     dbtype = db.DB_BTREE
       
   289 
       
   290 class AssociateRecnoTestCase(AssociateTestCase):
       
   291     dbtype = db.DB_RECNO
       
   292     keytype = 0
       
   293 
       
   294 #----------------------------------------------------------------------
       
   295 
       
   296 class AssociateBTreeTxnTestCase(AssociateBTreeTestCase):
       
   297     envFlags = db.DB_INIT_TXN
       
   298     dbFlags = 0
       
   299 
       
   300     def txn_finish_test(self, sDB, txn):
       
   301         try:
       
   302             self.finish_test(sDB, txn=txn)
       
   303         finally:
       
   304             if self.cur:
       
   305                 self.cur.close()
       
   306                 self.cur = None
       
   307             if txn:
       
   308                 txn.commit()
       
   309 
       
   310     def test13_associate_in_transaction(self):
       
   311         if verbose:
       
   312             print '\n', '-=' * 30
       
   313             print "Running %s.test13_associateAutoCommit..." % \
       
   314                   self.__class__.__name__
       
   315 
       
   316         txn = self.env.txn_begin()
       
   317         try:
       
   318             self.createDB(txn=txn)
       
   319 
       
   320             self.secDB = db.DB(self.env)
       
   321             self.secDB.set_flags(db.DB_DUP)
       
   322             self.secDB.set_get_returns_none(2)
       
   323             self.secDB.open(self.filename, "secondary", db.DB_BTREE,
       
   324                        db.DB_CREATE | db.DB_THREAD, txn=txn)
       
   325             if db.version() >= (4,1):
       
   326                 self.getDB().associate(self.secDB, self.getGenre, txn=txn)
       
   327             else:
       
   328                 self.getDB().associate(self.secDB, self.getGenre)
       
   329 
       
   330             self.addDataToDB(self.getDB(), txn=txn)
       
   331         except:
       
   332             txn.abort()
       
   333             raise
       
   334 
       
   335         self.txn_finish_test(self.secDB, txn=txn)
       
   336 
       
   337 
       
   338 #----------------------------------------------------------------------
       
   339 
       
   340 class ShelveAssociateTestCase(AssociateTestCase):
       
   341 
       
   342     def createDB(self):
       
   343         self.primary = dbshelve.open(self.filename,
       
   344                                      dbname="primary",
       
   345                                      dbenv=self.env,
       
   346                                      filetype=self.dbtype)
       
   347 
       
   348     def addDataToDB(self, d):
       
   349         for key, value in musicdata.items():
       
   350             if type(self.keytype) == type(''):
       
   351                 key = "%02d" % key
       
   352             d.put(key, value)    # save the value as is this time
       
   353 
       
   354 
       
   355     def getGenre(self, priKey, priData):
       
   356         self.assertEqual(type(priData), type(()))
       
   357         if verbose:
       
   358             print 'getGenre key: %r data: %r' % (priKey, priData)
       
   359         genre = priData[2]
       
   360         if genre == 'Blues':
       
   361             return db.DB_DONOTINDEX
       
   362         else:
       
   363             return genre
       
   364 
       
   365 
       
   366 class ShelveAssociateHashTestCase(ShelveAssociateTestCase):
       
   367     dbtype = db.DB_HASH
       
   368 
       
   369 class ShelveAssociateBTreeTestCase(ShelveAssociateTestCase):
       
   370     dbtype = db.DB_BTREE
       
   371 
       
   372 class ShelveAssociateRecnoTestCase(ShelveAssociateTestCase):
       
   373     dbtype = db.DB_RECNO
       
   374     keytype = 0
       
   375 
       
   376 
       
   377 #----------------------------------------------------------------------
       
   378 
       
   379 class ThreadedAssociateTestCase(AssociateTestCase):
       
   380 
       
   381     def addDataToDB(self, d):
       
   382         t1 = Thread(target = self.writer1,
       
   383                     args = (d, ))
       
   384         t2 = Thread(target = self.writer2,
       
   385                     args = (d, ))
       
   386 
       
   387         t1.setDaemon(True)
       
   388         t2.setDaemon(True)
       
   389         t1.start()
       
   390         t2.start()
       
   391         t1.join()
       
   392         t2.join()
       
   393 
       
   394     def writer1(self, d):
       
   395         for key, value in musicdata.items():
       
   396             if type(self.keytype) == type(''):
       
   397                 key = "%02d" % key
       
   398             d.put(key, '|'.join(value))
       
   399 
       
   400     def writer2(self, d):
       
   401         for x in range(100, 600):
       
   402             key = 'z%2d' % x
       
   403             value = [key] * 4
       
   404             d.put(key, '|'.join(value))
       
   405 
       
   406 
       
   407 class ThreadedAssociateHashTestCase(ShelveAssociateTestCase):
       
   408     dbtype = db.DB_HASH
       
   409 
       
   410 class ThreadedAssociateBTreeTestCase(ShelveAssociateTestCase):
       
   411     dbtype = db.DB_BTREE
       
   412 
       
   413 class ThreadedAssociateRecnoTestCase(ShelveAssociateTestCase):
       
   414     dbtype = db.DB_RECNO
       
   415     keytype = 0
       
   416 
       
   417 
       
   418 #----------------------------------------------------------------------
       
   419 
       
   420 def test_suite():
       
   421     suite = unittest.TestSuite()
       
   422 
       
   423     suite.addTest(unittest.makeSuite(AssociateErrorTestCase))
       
   424 
       
   425     suite.addTest(unittest.makeSuite(AssociateHashTestCase))
       
   426     suite.addTest(unittest.makeSuite(AssociateBTreeTestCase))
       
   427     suite.addTest(unittest.makeSuite(AssociateRecnoTestCase))
       
   428 
       
   429     if db.version() >= (4, 1):
       
   430         suite.addTest(unittest.makeSuite(AssociateBTreeTxnTestCase))
       
   431 
       
   432     suite.addTest(unittest.makeSuite(ShelveAssociateHashTestCase))
       
   433     suite.addTest(unittest.makeSuite(ShelveAssociateBTreeTestCase))
       
   434     suite.addTest(unittest.makeSuite(ShelveAssociateRecnoTestCase))
       
   435 
       
   436     if have_threads:
       
   437         suite.addTest(unittest.makeSuite(ThreadedAssociateHashTestCase))
       
   438         suite.addTest(unittest.makeSuite(ThreadedAssociateBTreeTestCase))
       
   439         suite.addTest(unittest.makeSuite(ThreadedAssociateRecnoTestCase))
       
   440 
       
   441     return suite
       
   442 
       
   443 
       
   444 if __name__ == '__main__':
       
   445     unittest.main(defaultTest='test_suite')