Changeset 9726 for main/waeup.kofa/trunk/src/waeup
- Timestamp:
- 26 Nov 2012, 23:27:46 (12 years ago)
- Location:
- main/waeup.kofa/trunk/src/waeup/kofa
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
main/waeup.kofa/trunk/src/waeup/kofa/interfaces.py
r9718 r9726 1217 1217 Returns ``None`` if no such entry can be found. 1218 1218 """ 1219 1220 class IExportContainerFinder(Interface): 1221 """A finder for the central export container. 1222 """ 1223 def __call__(): 1224 """Return the currently used global or site-wide IExportContainer. 1225 """ -
main/waeup.kofa/trunk/src/waeup/kofa/utils/batching.py
r9718 r9726 32 32 from zope.component import createObject, getUtility 33 33 from zope.component.hooks import setSite 34 from zope.interface import Interface 34 from zope.interface import Interface, implementer 35 35 from zope.schema import getFields 36 36 from zope.event import notify … … 39 39 IBatchProcessor, FatalCSVError, IObjectConverter, IJobManager, 40 40 ICSVExporter, IGNORE_MARKER, DuplicationError, JOB_STATUS_MAP, 41 IExportJobContainer, IExportJob )41 IExportJobContainer, IExportJob, IExportContainerFinder) 42 42 43 43 class BatchProcessor(grok.GlobalUtility): … … 672 672 return entry 673 673 return None 674 675 class VirtualExportJobContainer(ExportJobContainer): 676 """A virtual export job container. 677 678 Virtual ExportJobContainers can be used as a mixin just like real 679 ExportJobContainer. 680 681 They retrieve and store data in the site-wide ExportJobContainer. 682 683 Functionality is currently entirely as for regular 684 ExportJobContainers, except that data is stored elsewhere. 685 686 VirtualExportJobContainers need a registered 687 IExportContainerFinder utility to find a suitable container for 688 storing data. 689 """ 690 grok.implements(IExportJobContainer) 691 692 @property 693 def _site_container(self): 694 return getUtility(IExportContainerFinder)() 695 696 # The following is a simple trick. While ExportJobContainers store 697 # only one attribute in ZODB, it is sufficient to replace this 698 # attribute `running_exports` with a suitable manager to make the 699 # whole virtual container work like the original but with the data 700 # stored in the site-wide exports container. This way, virtual 701 # export containers provide the whole functionality of a regular 702 # exports container but store no data at all with themselves. 703 @property 704 def running_exports(self): 705 """Exports stored in the site-wide exports container. 706 """ 707 return self._site_container.running_exports 708 709 @running_exports.setter 710 def running_exports(self, value): 711 self._site_container.running_exports = value 712 713 @running_exports.deleter 714 def running_exports(self): 715 del self._site_container.running_exports 716 717 718 @implementer(IExportContainerFinder) 719 class ExportContainerFinder(grok.GlobalUtility): 720 """Finder for local (site-wide) export container. 721 """ 722 723 def __call__(self): 724 """Get the local export container- 725 726 If no site can be determined or the site provides no export 727 container, None is returned. 728 """ 729 site = grok.getSite() 730 if site is None: 731 return None 732 return site.get('datacenter', None) -
main/waeup.kofa/trunk/src/waeup/kofa/utils/tests/test_batching.py
r9342 r9726 25 25 from zc.async.interfaces import IJob 26 26 from zope import schema 27 from zope.component import provideUtility, getGlobalSiteManager 27 from zope.component import provideUtility, getGlobalSiteManager, getUtility 28 28 from zope.component.factory import Factory 29 from zope.component.hooks import clearSite 29 from zope.component.hooks import clearSite, setSite 30 30 from zope.component.interfaces import IFactory 31 31 from zope.interface import Interface, implements, verify … … 33 33 from waeup.kofa.interfaces import ( 34 34 ICSVExporter, IBatchProcessor, IExportJobContainer, IJobManager, 35 IExportJob )35 IExportJob, IExportContainerFinder) 36 36 from waeup.kofa.testing import ( 37 37 FunctionalLayer, FunctionalTestCase, FakeJob, FakeJobManager) 38 38 from waeup.kofa.utils.batching import ( 39 39 ExporterBase, BatchProcessor, export_job, AsyncExportJob, 40 ExportJobContainer )40 ExportJobContainer, VirtualExportJobContainer, ExportContainerFinder) 41 41 42 42 optionflags = ( … … 396 396 # Test ExportJobContainer 397 397 398 TestedClass = ExportJobContainer 399 398 400 def setUp(self): 399 401 # register a suitable ICSVExporter as named utility … … 412 414 def test_export_job_interfaces(self): 413 415 # the ExportJobContainer implements promised interfaces correctly... 414 container = ExportJobContainer()415 verify.verifyClass(IExportJobContainer, ExportJobContainer)416 container = self.TestedClass() 417 verify.verifyClass(IExportJobContainer, self.TestedClass) 416 418 verify.verifyObject(IExportJobContainer, container) 417 419 return … … 419 421 def test_start_export_job(self): 420 422 # we can start jobs 421 container = ExportJobContainer()423 container = self.TestedClass() 422 424 container.start_export_job('cave_exporter', 'bob') 423 425 result = self.job_manager._jobs.values()[0] … … 431 433 def test_get_running_export_jobs_all(self): 432 434 # we can get export jobs of all users 433 container = ExportJobContainer()435 container = self.TestedClass() 434 436 container.start_export_job('cave_exporter', 'bob') 435 437 container.start_export_job('cave_exporter', 'alice') … … 444 446 def test_get_running_export_jobs_user(self): 445 447 # we can get the export jobs running for a certain user 446 container = ExportJobContainer()448 container = self.TestedClass() 447 449 container.start_export_job('cave_exporter', 'bob') 448 450 container.start_export_job('cave_exporter', 'alice') … … 457 459 def test_get_running_export_jobs_only_if_exist(self): 458 460 # we get only jobs that are accessible through the job manager... 459 container = ExportJobContainer()461 container = self.TestedClass() 460 462 container.start_export_job('cave_exporter', 'bob') 461 463 container.start_export_job('cave_exporter', 'bob') … … 473 475 def test_get_export_job_status(self): 474 476 # we can get the stati of jobs... 475 container = ExportJobContainer()477 container = self.TestedClass() 476 478 container.start_export_job('cave_exporter', 'alice') 477 479 container.start_export_job('cave_exporter', 'bob') … … 490 492 # we can remove export entries in local lists and the job 491 493 # manager as well... 492 container = ExportJobContainer()494 container = self.TestedClass() 493 495 container.start_export_job('cave_exporter', 'bob') 494 496 entry = container.running_exports[0] … … 503 505 def test_delete_export_entry_remove_file(self): 504 506 # any result files of exports are deleted as well 505 container = ExportJobContainer()507 container = self.TestedClass() 506 508 entry = ('4', 'cave_exporter', 'bob') 507 509 container.running_exports = [entry] … … 515 517 def test_entry_from_job_id(self): 516 518 # we can get an entry for a job_id if the id exists 517 container = ExportJobContainer()519 container = self.TestedClass() 518 520 entry = ('4', 'cave_exporter', 'bob') 519 521 container.running_exports = [entry] … … 528 530 shutil.rmtree(fake_job.dir_path) 529 531 return 532 533 class VirtualExportJobContainerTests(ExportJobContainerTests): 534 # VirtualExportJobContainers should provide the 535 # same functionality as regular ones. 536 537 TestedClass = VirtualExportJobContainer 538 539 def setUp(self): 540 super(VirtualExportJobContainerTests, self).setUp() 541 self.root_job_container = ExportJobContainer() 542 def fake_finder(): 543 return self.root_job_container 544 self.gsm = getGlobalSiteManager() 545 self.gsm.registerUtility(fake_finder, IExportContainerFinder) 546 return 547 548 class ExportContainerFinderTests(FunctionalTestCase): 549 # Tests for export container finder. 550 551 layer = FunctionalLayer 552 553 def test_get_finder_as_util(self): 554 # we can get a finder by utility lookup 555 finder = getUtility(IExportContainerFinder) 556 self.assertTrue(finder is not None) 557 self.assertEqual( 558 IExportContainerFinder.providedBy(finder), 559 True) 560 return 561 562 def test_iface(self): 563 # the finder complies with the promised interface 564 finder = ExportContainerFinder() 565 verify.verifyClass(IExportContainerFinder, 566 ExportContainerFinder) 567 verify.verifyObject(IExportContainerFinder, finder) 568 return 569 570 def test_no_site(self): 571 # a finder returns None if no site is available 572 finder = ExportContainerFinder() 573 self.assertEqual( 574 finder(), None) 575 return 576 577 def test_active_site(self): 578 # we get the datafinder if one is installed and site set 579 self.getRootFolder()['app'] = University() 580 finder = getUtility(IExportContainerFinder) 581 setSite(self.getRootFolder()['app']) 582 container = finder() 583 self.assertTrue(container is not None) 584 return 585 586 def test_broken_site(self): 587 # if the current site has no ExportContainer, we get None 588 self.getRootFolder()['app'] = University() 589 app = self.getRootFolder()['app'] 590 del app['datacenter'] # datacenter _is_ the export container 591 setSite(app) 592 finder = getUtility(IExportContainerFinder) 593 container = finder() 594 self.assertTrue(container is None) 595 return
Note: See TracChangeset for help on using the changeset viewer.