Mercurial > p > roundup > code
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: |
