comparison test/test_db.py @ 854:3cdfa5d86cec

Added metakit backend to the db tests... ...and fixed the more easily fixable test failures.
author Richard Jones <richard@users.sourceforge.net>
date Thu, 11 Jul 2002 01:11:03 +0000
parents 6d7a45c8464a
children 2dd862af72ee
comparison
equal deleted inserted replaced
851:ced1fa60b9e2 854:3cdfa5d86cec
13 # BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 13 # BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14 # FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" 14 # FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS"
15 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, 15 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
16 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 16 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
17 # 17 #
18 # $Id: test_db.py,v 1.25 2002-07-09 04:19:09 richard Exp $ 18 # $Id: test_db.py,v 1.26 2002-07-11 01:11:03 richard Exp $
19 19
20 import unittest, os, shutil 20 import unittest, os, shutil
21 21
22 from roundup.hyperdb import String, Password, Link, Multilink, Date, \ 22 from roundup.hyperdb import String, Password, Link, Multilink, Date, \
23 Interval, Class, DatabaseError 23 Interval, DatabaseError, Class
24 from roundup.roundupdb import FileClass 24 from roundup.roundupdb import FileClass
25 from roundup import date, password 25 from roundup import date, password
26 from roundup.indexer import Indexer 26 from roundup.indexer import Indexer
27 27
28 def setupSchema(db, create): 28 def setupSchema(db, create, Class, FileClass):
29 status = Class(db, "status", name=String()) 29 status = Class(db, "status", name=String())
30 status.setkey("name") 30 status.setkey("name")
31 user = Class(db, "user", username=String(), password=Password()) 31 user = Class(db, "user", username=String(), password=Password())
32 file = FileClass(db, "file", name=String(), type=String(), 32 file = FileClass(db, "file", name=String(), type=String(),
33 comment=String(indexme="yes")) 33 comment=String(indexme="yes"))
67 # remove previous test, ignore errors 67 # remove previous test, ignore errors
68 if os.path.exists(config.DATABASE): 68 if os.path.exists(config.DATABASE):
69 shutil.rmtree(config.DATABASE) 69 shutil.rmtree(config.DATABASE)
70 os.makedirs(config.DATABASE + '/files') 70 os.makedirs(config.DATABASE + '/files')
71 self.db = anydbm.Database(config, 'test') 71 self.db = anydbm.Database(config, 'test')
72 setupSchema(self.db, 1) 72 setupSchema(self.db, 1, Class, FileClass)
73 self.db2 = anydbm.Database(config, 'test') 73 self.db2 = anydbm.Database(config, 'test')
74 setupSchema(self.db2, 0) 74 setupSchema(self.db2, 0, Class, FileClass)
75 75
76 def testStringChange(self): 76 def testStringChange(self):
77 self.db.issue.create(title="spam", status='1') 77 self.db.issue.create(title="spam", status='1')
78 self.assertEqual(self.db.issue.get('1', 'title'), 'spam') 78 self.assertEqual(self.db.issue.get('1', 'title'), 'spam')
79 self.db.issue.set('1', title='eggs') 79 self.db.issue.set('1', title='eggs')
109 a = self.db.issue.get('1', "foo") 109 a = self.db.issue.get('1', "foo")
110 self.db.issue.set('1', foo=date.Interval('-1d')) 110 self.db.issue.set('1', foo=date.Interval('-1d'))
111 self.assertNotEqual(self.db.issue.get('1', "foo"), a) 111 self.assertNotEqual(self.db.issue.get('1', "foo"), a)
112 112
113 def testNewProperty(self): 113 def testNewProperty(self):
114 ' make sure a new property is added ok '
114 self.db.issue.create(title="spam", status='1') 115 self.db.issue.create(title="spam", status='1')
115 self.db.issue.addprop(fixer=Link("user")) 116 self.db.issue.addprop(fixer=Link("user"))
116 props = self.db.issue.getprops() 117 props = self.db.issue.getprops()
117 keys = props.keys() 118 keys = props.keys()
118 keys.sort() 119 keys.sort()
201 202
202 # 203 #
203 # class get 204 # class get
204 # 205 #
205 # invalid node id 206 # invalid node id
206 ar(IndexError, self.db.status.get, '10', 'name') 207 ar(IndexError, self.db.issue.get, '1', 'title')
207 # invalid property name 208 # invalid property name
208 ar(KeyError, self.db.status.get, '2', 'foo') 209 ar(KeyError, self.db.status.get, '2', 'foo')
209 210
210 # 211 #
211 # class set 212 # class set
212 # 213 #
213 # invalid node id 214 # invalid node id
214 ar(IndexError, self.db.issue.set, '1', name='foo') 215 ar(IndexError, self.db.issue.set, '1', title='foo')
215 # invalid property name 216 # invalid property name
216 ar(KeyError, self.db.status.set, '1', foo='foo') 217 ar(KeyError, self.db.status.set, '1', foo='foo')
217 # string property 218 # string property
218 ar(TypeError, self.db.status.set, '1', name=1) 219 ar(TypeError, self.db.status.set, '1', name=1)
219 # key name clash 220 # key name clash
344 # remove previous test, ignore errors 345 # remove previous test, ignore errors
345 if os.path.exists(config.DATABASE): 346 if os.path.exists(config.DATABASE):
346 shutil.rmtree(config.DATABASE) 347 shutil.rmtree(config.DATABASE)
347 os.makedirs(config.DATABASE + '/files') 348 os.makedirs(config.DATABASE + '/files')
348 db = anydbm.Database(config, 'test') 349 db = anydbm.Database(config, 'test')
349 setupSchema(db, 1) 350 setupSchema(db, 1, Class, FileClass)
350 self.db = anydbm.Database(config) 351 self.db = anydbm.Database(config)
351 setupSchema(self.db, 0) 352 setupSchema(self.db, 0, Class, FileClass)
352 self.db2 = anydbm.Database(config, 'test') 353 self.db2 = anydbm.Database(config, 'test')
353 setupSchema(self.db2, 0) 354 setupSchema(self.db2, 0, Class, FileClass)
354 355
355 def testExceptions(self): 356 def testExceptions(self):
357 ' make sure exceptions are raised on writes to a read-only db '
356 # this tests the exceptions that should be raised 358 # this tests the exceptions that should be raised
357 ar = self.assertRaises 359 ar = self.assertRaises
358 360
359 # this tests the exceptions that should be raised 361 # this tests the exceptions that should be raised
360 ar(DatabaseError, self.db.status.create, name="foo") 362 ar(DatabaseError, self.db.status.create, name="foo")
368 # remove previous test, ignore errors 370 # remove previous test, ignore errors
369 if os.path.exists(config.DATABASE): 371 if os.path.exists(config.DATABASE):
370 shutil.rmtree(config.DATABASE) 372 shutil.rmtree(config.DATABASE)
371 os.makedirs(config.DATABASE + '/files') 373 os.makedirs(config.DATABASE + '/files')
372 self.db = bsddb.Database(config, 'test') 374 self.db = bsddb.Database(config, 'test')
373 setupSchema(self.db, 1) 375 setupSchema(self.db, 1, Class, FileClass)
374 self.db2 = bsddb.Database(config, 'test') 376 self.db2 = bsddb.Database(config, 'test')
375 setupSchema(self.db2, 0) 377 setupSchema(self.db2, 0, Class, FileClass)
376 378
377 class bsddbReadOnlyDBTestCase(anydbmReadOnlyDBTestCase): 379 class bsddbReadOnlyDBTestCase(anydbmReadOnlyDBTestCase):
378 def setUp(self): 380 def setUp(self):
379 from roundup.backends import bsddb 381 from roundup.backends import bsddb
380 # remove previous test, ignore errors 382 # remove previous test, ignore errors
381 if os.path.exists(config.DATABASE): 383 if os.path.exists(config.DATABASE):
382 shutil.rmtree(config.DATABASE) 384 shutil.rmtree(config.DATABASE)
383 os.makedirs(config.DATABASE + '/files') 385 os.makedirs(config.DATABASE + '/files')
384 db = bsddb.Database(config, 'test') 386 db = bsddb.Database(config, 'test')
385 setupSchema(db, 1) 387 setupSchema(db, 1, Class, FileClass)
386 self.db = bsddb.Database(config) 388 self.db = bsddb.Database(config)
387 setupSchema(self.db, 0) 389 setupSchema(self.db, 0, Class, FileClass)
388 self.db2 = bsddb.Database(config, 'test') 390 self.db2 = bsddb.Database(config, 'test')
389 setupSchema(self.db2, 0) 391 setupSchema(self.db2, 0, Class, FileClass)
390 392
391 393
392 class bsddb3DBTestCase(anydbmDBTestCase): 394 class bsddb3DBTestCase(anydbmDBTestCase):
393 def setUp(self): 395 def setUp(self):
394 from roundup.backends import bsddb3 396 from roundup.backends import bsddb3
395 # remove previous test, ignore errors 397 # remove previous test, ignore errors
396 if os.path.exists(config.DATABASE): 398 if os.path.exists(config.DATABASE):
397 shutil.rmtree(config.DATABASE) 399 shutil.rmtree(config.DATABASE)
398 os.makedirs(config.DATABASE + '/files') 400 os.makedirs(config.DATABASE + '/files')
399 self.db = bsddb3.Database(config, 'test') 401 self.db = bsddb3.Database(config, 'test')
400 setupSchema(self.db, 1) 402 setupSchema(self.db, 1, Class, FileClass)
401 self.db2 = bsddb3.Database(config, 'test') 403 self.db2 = bsddb3.Database(config, 'test')
402 setupSchema(self.db2, 0) 404 setupSchema(self.db2, 0, Class, FileClass)
403 405
404 class bsddb3ReadOnlyDBTestCase(anydbmReadOnlyDBTestCase): 406 class bsddb3ReadOnlyDBTestCase(anydbmReadOnlyDBTestCase):
405 def setUp(self): 407 def setUp(self):
406 from roundup.backends import bsddb3 408 from roundup.backends import bsddb3
407 # remove previous test, ignore errors 409 # remove previous test, ignore errors
408 if os.path.exists(config.DATABASE): 410 if os.path.exists(config.DATABASE):
409 shutil.rmtree(config.DATABASE) 411 shutil.rmtree(config.DATABASE)
410 os.makedirs(config.DATABASE + '/files') 412 os.makedirs(config.DATABASE + '/files')
411 db = bsddb3.Database(config, 'test') 413 db = bsddb3.Database(config, 'test')
412 setupSchema(db, 1) 414 setupSchema(db, 1, Class, FileClass)
413 self.db = bsddb3.Database(config) 415 self.db = bsddb3.Database(config)
414 setupSchema(self.db, 0) 416 setupSchema(self.db, 0, Class, FileClass)
415 self.db2 = bsddb3.Database(config, 'test') 417 self.db2 = bsddb3.Database(config, 'test')
416 setupSchema(self.db2, 0) 418 setupSchema(self.db2, 0, Class, FileClass)
417 419
420
421 class metakitDBTestCase(anydbmDBTestCase):
422 def setUp(self):
423 from roundup.backends import metakit
424 import weakref
425 metakit._instances = weakref.WeakValueDictionary()
426 # remove previous test, ignore errors
427 if os.path.exists(config.DATABASE):
428 shutil.rmtree(config.DATABASE)
429 os.makedirs(config.DATABASE + '/files')
430 self.db = metakit.Database(config, 'test')
431 setupSchema(self.db, 1, metakit.Class, metakit.FileClass)
432 self.db2 = metakit.Database(config, 'test')
433 setupSchema(self.db2, 0, metakit.Class, metakit.FileClass)
434
435 def testTransactions(self):
436 # remember the number of items we started
437 num_issues = len(self.db.issue.list())
438 self.db.issue.create(title="don't commit me!", status='1')
439 self.assertNotEqual(num_issues, len(self.db.issue.list()))
440 self.db.rollback()
441 self.assertEqual(num_issues, len(self.db.issue.list()))
442 self.db.issue.create(title="please commit me!", status='1')
443 self.assertNotEqual(num_issues, len(self.db.issue.list()))
444 self.db.commit()
445 self.assertNotEqual(num_issues, len(self.db.issue.list()))
446 self.db.rollback()
447 self.assertNotEqual(num_issues, len(self.db.issue.list()))
448 self.db.file.create(name="test", type="text/plain", content="hi")
449 self.db.rollback()
450 for i in range(10):
451 self.db.file.create(name="test", type="text/plain",
452 content="hi %d"%(i))
453 self.db.commit()
454 # TODO: would be good to be able to ensure the file is not on disk after
455 # a rollback...
456 self.assertNotEqual(num_files, num_files2)
457 self.db.file.create(name="test", type="text/plain", content="hi")
458 self.db.rollback()
459
460 def testNewProperty(self):
461 ' make sure a new property is added ok '
462 self.db.issue.create(title="spam", status='1')
463 self.db.issue.addprop(fixer=Link("user"))
464 props = self.db.issue.getprops()
465 keys = props.keys()
466 keys.sort()
467 # metakit _base_ Class has the activity, creation and creator too
468 self.assertEqual(keys, ['activity', 'creation', 'creator',
469 'deadline', 'files', 'fixer', 'foo', 'id', 'nosy', 'status',
470 'title'])
471 self.assertEqual(self.db.issue.get('1', "fixer"), None)
472
473 class metakitReadOnlyDBTestCase(anydbmReadOnlyDBTestCase):
474 def setUp(self):
475 from roundup.backends import metakit
476 import weakref
477 metakit._instances = weakref.WeakValueDictionary()
478 # remove previous test, ignore errors
479 if os.path.exists(config.DATABASE):
480 shutil.rmtree(config.DATABASE)
481 os.makedirs(config.DATABASE + '/files')
482 db = metakit.Database(config, 'test')
483 setupSchema(db, 1, metakit.Class, metakit.FileClass)
484 self.db = metakit.Database(config)
485 setupSchema(self.db, 0, metakit.Class, metakit.FileClass)
486 self.db2 = metakit.Database(config, 'test')
487 setupSchema(self.db2, 0, metakit.Class, metakit.FileClass)
418 488
419 def suite(): 489 def suite():
420 l = [ 490 l = [
421 unittest.makeSuite(anydbmDBTestCase, 'test'), 491 unittest.makeSuite(anydbmDBTestCase, 'test'),
422 unittest.makeSuite(anydbmReadOnlyDBTestCase, 'test') 492 unittest.makeSuite(anydbmReadOnlyDBTestCase, 'test')
434 l.append(unittest.makeSuite(bsddb3DBTestCase, 'test')) 504 l.append(unittest.makeSuite(bsddb3DBTestCase, 'test'))
435 l.append(unittest.makeSuite(bsddb3ReadOnlyDBTestCase, 'test')) 505 l.append(unittest.makeSuite(bsddb3ReadOnlyDBTestCase, 'test'))
436 except: 506 except:
437 print 'bsddb3 module not found, skipping bsddb3 DBTestCase' 507 print 'bsddb3 module not found, skipping bsddb3 DBTestCase'
438 508
509 try:
510 import metakit
511 l.append(unittest.makeSuite(metakitDBTestCase, 'test'))
512 l.append(unittest.makeSuite(metakitReadOnlyDBTestCase, 'test'))
513 except:
514 print 'metakit module not found, skipping metakit DBTestCase'
515
439 return unittest.TestSuite(l) 516 return unittest.TestSuite(l)
440 517
441 # 518 #
442 # $Log: not supported by cvs2svn $ 519 # $Log: not supported by cvs2svn $
520 # Revision 1.25 2002/07/09 04:19:09 richard
521 # Added reindex command to roundup-admin.
522 # Fixed reindex on first access.
523 # Also fixed reindexing of entries that change.
524 #
443 # Revision 1.24 2002/07/09 03:02:53 richard 525 # Revision 1.24 2002/07/09 03:02:53 richard
444 # More indexer work: 526 # More indexer work:
445 # - all String properties may now be indexed too. Currently there's a bit of 527 # - all String properties may now be indexed too. Currently there's a bit of
446 # "issue" specific code in the actual searching which needs to be 528 # "issue" specific code in the actual searching which needs to be
447 # addressed. In a nutshell: 529 # addressed. In a nutshell:

Roundup Issue Tracker: http://roundup-tracker.org/