##############################################################################
#
# Copyright (c) 2005 Zope Corporation and Contributors. All Rights
# Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this
# distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
""" Unit tests for GenericSetup-based export / import of PluginRegistry.
$Id: test_exportimport.py 74716 2007-04-24 19:15:04Z tseaver $
"""
import unittest
try:
import Products.GenericSetup
except ImportError: # No GenericSetup, so no tests
print 'XXXX: No GenericSetup!'
def test_suite():
return unittest.TestSuite()
else:
from Products.GenericSetup.tests.common import BaseRegistryTests
from Products.GenericSetup.tests.common import DummyExportContext
from Products.GenericSetup.tests.common import DummyImportContext
from Products.GenericSetup.utils import _getDottedName
from zope.interface import Interface
from zope.interface import directlyProvides
from zope.app.testing import ztapi
try:
from zope.traversing.interfaces import ITraversable
from zope.traversing.interfaces import TraversalError
except ImportError:
# BBB for Zope 2.9
from zope.app.traversing.interfaces import ITraversable
from zope.app.traversing.interfaces import TraversalError
try:
from zope.app.testing.placelesssetup import PlacelessSetup
except ImportError:
# BBB for Zope 2.8
from zope.app.tests.placelesssetup import PlacelessSetup
class IFoo(Interface):
pass
class IBar(Interface):
pass
_EMPTY_PLUGINREGISTRY_EXPORT = """\
"""
_PLUGIN_TYPE_INFO = (
( IFoo
, 'IFoo'
, 'foo'
, "Some plugin interface"
)
, ( IBar
, 'IBar'
, 'bar'
, "Another plugin interface"
)
)
_NO_PLUGINS_PLUGINREGISTRY_EXPORT = """\
""" % (_getDottedName(IFoo), _getDottedName(IBar))
_NORMAL_PLUGINREGISTRY_EXPORT = """\
""" % (_getDottedName(IFoo), _getDottedName(IBar))
class _TestBase(PlacelessSetup, BaseRegistryTests):
def _initRegistry(self, plugin_type_info=(), plugins={}):
from OFS.Folder import Folder
from OFS.SimpleItem import SimpleItem
from Products.PluginRegistry.PluginRegistry import PluginRegistry
app = Folder()
app.getPhysicalPath = lambda: ()
app.getPhysicalRoot = lambda: app
app._setObject('foo_plugin_1', SimpleItem())
app._setObject('foo_plugin_2', SimpleItem())
registry = PluginRegistry(plugin_type_info)
registry._plugins = {} # it is usually lazy
for plugin_type, registered in plugins.items():
for obj_id in registered:
obj = app._getOb(obj_id)
directlyProvides(obj, plugin_type)
registry._plugins[plugin_type] = registered
app._setObject('plugin_registry', registry)
registry = app._getOb('plugin_registry')
return app, registry
class PluginRegistryExporterTests(_TestBase):
def _getTargetClass(self):
from Products.PluginRegistry.exportimport \
import PluginRegistryExporter
return PluginRegistryExporter
def test_empty(self):
ztapi.provideAdapter(None, ITraversable, AttrItemTraverser)
app, registry = self._initRegistry()
exporter = self._makeOne(registry).__of__(registry)
xml = exporter.generateXML()
self._compareDOM(xml, _EMPTY_PLUGINREGISTRY_EXPORT)
def test_normal_no_plugins(self):
ztapi.provideAdapter(None, ITraversable, AttrItemTraverser)
app, registry = self._initRegistry(
plugin_type_info=_PLUGIN_TYPE_INFO)
exporter = self._makeOne(registry).__of__(registry)
xml = exporter.generateXML()
self._compareDOM(xml, _NO_PLUGINS_PLUGINREGISTRY_EXPORT)
def test_normal_with_plugins(self):
ztapi.provideAdapter(None, ITraversable, AttrItemTraverser)
app, registry = self._initRegistry(
plugin_type_info=_PLUGIN_TYPE_INFO,
plugins={IFoo: ('foo_plugin_1',
'foo_plugin_2')},
)
exporter = self._makeOne(registry).__of__(registry)
xml = exporter.generateXML()
self._compareDOM(xml, _NORMAL_PLUGINREGISTRY_EXPORT)
class Test_exportPluginRegistry(_TestBase):
def test_empty(self):
from Products.PluginRegistry.exportimport \
import exportPluginRegistry
ztapi.provideAdapter(None, ITraversable, AttrItemTraverser)
app, registry = self._initRegistry()
context = DummyExportContext(app)
exportPluginRegistry(context)
self.assertEqual( len(context._wrote), 1 )
filename, text, content_type = context._wrote[0]
self.assertEqual(filename, 'pluginregistry.xml')
self._compareDOM(text, _EMPTY_PLUGINREGISTRY_EXPORT)
self.assertEqual(content_type, 'text/xml')
def test_normal_no_plugins(self):
from Products.PluginRegistry.exportimport \
import exportPluginRegistry
ztapi.provideAdapter(None, ITraversable, AttrItemTraverser)
app, registry = self._initRegistry(
plugin_type_info=_PLUGIN_TYPE_INFO)
context = DummyExportContext(app)
exportPluginRegistry(context)
self.assertEqual( len(context._wrote), 1 )
filename, text, content_type = context._wrote[0]
self.assertEqual(filename, 'pluginregistry.xml')
self._compareDOM(text, _NO_PLUGINS_PLUGINREGISTRY_EXPORT)
self.assertEqual(content_type, 'text/xml')
def test_normal_with_plugins(self):
from Products.PluginRegistry.exportimport \
import exportPluginRegistry
ztapi.provideAdapter(None, ITraversable, AttrItemTraverser)
app, registry = self._initRegistry(
plugin_type_info=_PLUGIN_TYPE_INFO,
plugins={IFoo: ('foo_plugin_1',
'foo_plugin_2')},
)
context = DummyExportContext(app)
exportPluginRegistry(context)
self.assertEqual( len(context._wrote), 1 )
filename, text, content_type = context._wrote[0]
self.assertEqual(filename, 'pluginregistry.xml')
self._compareDOM(text, _NORMAL_PLUGINREGISTRY_EXPORT)
self.assertEqual(content_type, 'text/xml')
class PluginRegistryImporterTests(_TestBase):
def _getTargetClass(self):
from Products.PluginRegistry.exportimport \
import PluginRegistryImporter
return PluginRegistryImporter
def test_parseXML_empty(self):
app, registry = self._initRegistry()
importer = self._makeOne(registry).__of__(registry)
reg_info = importer.parseXML(_EMPTY_PLUGINREGISTRY_EXPORT)
self.assertEqual( len( reg_info['plugin_types'] ), 0 )
def test_parseXML_normal_no_plugins(self):
app, registry = self._initRegistry()
importer = self._makeOne(registry).__of__(registry)
reg_info = importer.parseXML(_NO_PLUGINS_PLUGINREGISTRY_EXPORT)
self.assertEqual( len( reg_info['plugin_types'] ), 2 )
info = reg_info['plugin_types'][0]
self.assertEqual(info['id'], 'IFoo')
self.assertEqual(info['interface'], _getDottedName(IFoo))
self.assertEqual(info['title'], 'foo')
self.assertEqual(info['description'], 'Some plugin interface')
self.assertEqual(len( info['plugins'] ), 0)
info = reg_info['plugin_types'][1]
self.assertEqual(info['id'], 'IBar')
self.assertEqual(info['interface'], _getDottedName(IBar))
self.assertEqual(info['title'], 'bar')
self.assertEqual(info['description'], 'Another plugin interface')
self.assertEqual(len( info['plugins'] ), 0 )
def test_parseXML_normal_with_plugins(self):
app, registry = self._initRegistry()
importer = self._makeOne(registry).__of__(registry)
reg_info = importer.parseXML(_NORMAL_PLUGINREGISTRY_EXPORT)
self.assertEqual(len(reg_info['plugin_types'] ), 2 )
info = reg_info['plugin_types'][0]
self.assertEqual(info['id'], 'IFoo')
self.assertEqual(info['interface'], _getDottedName(IFoo))
self.assertEqual(info['title'], 'foo')
self.assertEqual(info['description'], 'Some plugin interface')
plugins = info['plugins']
self.assertEqual(len(plugins), 2)
self.assertEqual(plugins[0]['id'], 'foo_plugin_1')
self.assertEqual(plugins[1]['id'], 'foo_plugin_2')
info = reg_info['plugin_types'][1]
self.assertEqual(info['id'], 'IBar')
self.assertEqual(info['interface'], _getDottedName(IBar))
self.assertEqual(info['title'], 'bar')
self.assertEqual(info['description'], 'Another plugin interface')
self.assertEqual(len(info['plugins']), 0 )
class Test_importPluginRegistry(_TestBase):
def test_empty_default_purge(self):
from Products.PluginRegistry.exportimport \
import importPluginRegistry
app, registry = self._initRegistry(
plugin_type_info=_PLUGIN_TYPE_INFO,
plugins={IFoo: ('foo_plugin_1',
'foo_plugin_2')},
)
self.assertEqual(len(registry.listPluginTypeInfo()), 2)
self.assertEqual(len(registry.listPlugins(IFoo)), 2)
self.assertEqual(len(registry.listPlugins(IBar)), 0)
context = DummyImportContext(app)
context._files['pluginregistry.xml'] = _EMPTY_PLUGINREGISTRY_EXPORT
importPluginRegistry(context)
self.assertEqual(len(registry.listPluginTypeInfo()), 0)
self.assertRaises(KeyError, registry.listPlugins, IFoo)
self.assertRaises(KeyError, registry.listPlugins, IBar)
def test_empty_explicit_purge(self):
from Products.PluginRegistry.exportimport \
import importPluginRegistry
app, registry = self._initRegistry(
plugin_type_info=_PLUGIN_TYPE_INFO,
plugins={IFoo: ('foo_plugin_1',
'foo_plugin_2')},
)
self.assertEqual(len(registry.listPluginTypeInfo()), 2)
self.assertEqual(len(registry.listPlugins(IFoo)), 2)
self.assertEqual(len(registry.listPlugins(IBar)), 0)
context = DummyImportContext(app, True)
context._files['pluginregistry.xml'] = _EMPTY_PLUGINREGISTRY_EXPORT
importPluginRegistry(context)
self.assertEqual(len(registry.listPluginTypeInfo()), 0)
self.assertRaises(KeyError, registry.listPlugins, IFoo)
self.assertRaises(KeyError, registry.listPlugins, IBar)
def test_empty_skip_purge(self):
from Products.PluginRegistry.exportimport \
import importPluginRegistry
app, registry = self._initRegistry(
plugin_type_info=_PLUGIN_TYPE_INFO,
plugins={IFoo: ('foo_plugin_1',
'foo_plugin_2')},
)
self.assertEqual(len(registry.listPluginTypeInfo()), 2)
self.assertEqual(len(registry.listPlugins(IFoo)), 2)
self.assertEqual(len(registry.listPlugins(IBar)), 0)
context = DummyImportContext(app, False)
context._files['pluginregistry.xml'] = _EMPTY_PLUGINREGISTRY_EXPORT
importPluginRegistry(context)
self.assertEqual(len(registry.listPluginTypeInfo()), 2)
self.assertEqual(len(registry.listPlugins(IFoo)), 2)
self.assertEqual(len(registry.listPlugins(IBar)), 0)
def test_normal_no_plugins(self):
from Products.PluginRegistry.exportimport \
import importPluginRegistry
app, registry = self._initRegistry(plugins={IFoo: ('foo_plugin_1',
'foo_plugin_2')},
)
self.assertEqual(len(registry.listPluginTypeInfo()), 0)
self.assertRaises(KeyError, registry.listPlugins, IFoo)
self.assertRaises(KeyError, registry.listPlugins, IBar)
context = DummyImportContext(app, False)
context._files['pluginregistry.xml'
] = _NO_PLUGINS_PLUGINREGISTRY_EXPORT
importPluginRegistry(context)
self.assertEqual(len(registry.listPluginTypeInfo()), 2)
info = registry.listPluginTypeInfo()[0]
self.assertEqual(info['id'], 'IFoo')
self.assertEqual(info['title'], 'foo')
self.assertEqual(info['description'], 'Some plugin interface')
info = registry.listPluginTypeInfo()[1]
self.assertEqual(info['id'], 'IBar')
self.assertEqual(info['title'], 'bar')
self.assertEqual(info['description'], 'Another plugin interface')
self.assertEqual(len(registry.listPlugins(IFoo)), 0)
self.assertEqual(len(registry.listPlugins(IBar)), 0)
def test_normal_with_plugins(self):
from Products.PluginRegistry.exportimport \
import importPluginRegistry
app, registry = self._initRegistry(plugins={IFoo: ('foo_plugin_1',
'foo_plugin_2')},
)
self.assertEqual(len(registry.listPluginTypeInfo()), 0)
self.assertRaises(KeyError, registry.listPlugins, IFoo)
self.assertRaises(KeyError, registry.listPlugins, IBar)
context = DummyImportContext(app, False)
context._files['pluginregistry.xml'
] = _NORMAL_PLUGINREGISTRY_EXPORT
importPluginRegistry(context)
self.assertEqual(len(registry.listPluginTypeInfo()), 2)
info = registry.listPluginTypeInfo()[0]
self.assertEqual(info['id'], 'IFoo')
self.assertEqual(info['title'], 'foo')
self.assertEqual(info['description'], 'Some plugin interface')
info = registry.listPluginTypeInfo()[1]
self.assertEqual(info['id'], 'IBar')
self.assertEqual(info['title'], 'bar')
self.assertEqual(info['description'], 'Another plugin interface')
self.assertEqual(len(registry.listPlugins(IFoo)), 2)
plugins = registry.listPlugins(IFoo)
self.assertEqual(plugins[0][0], 'foo_plugin_1')
self.assertEqual(plugins[0][1], app._getOb('foo_plugin_1'))
self.assertEqual(plugins[1][0], 'foo_plugin_2')
self.assertEqual(plugins[1][1], app._getOb('foo_plugin_2'))
self.assertEqual(len(registry.listPlugins(IBar)), 0)
def test_normal_with_plugins_skip_duplicates(self):
# See http://www.zope.org/Collectors/PAS/52
from Products.PluginRegistry.exportimport \
import importPluginRegistry
app, registry = self._initRegistry()
self.assertEqual(len(registry.listPluginTypeInfo()), 0)
self.assertRaises(KeyError, registry.listPlugins, IFoo)
self.assertRaises(KeyError, registry.listPlugins, IBar)
context = DummyImportContext(app, False)
context._files['pluginregistry.xml'
] = _NORMAL_PLUGINREGISTRY_EXPORT
importPluginRegistry(context)
importPluginRegistry(context) # twice should not duplicate
self.assertEqual(len(registry.listPluginTypeInfo()), 2)
class AttrItemTraverser:
_marker = object()
def __init__(self, context):
self.context = context
def traverse(self, name, furtherPath):
result = getattr(self.context, name, self._marker)
if result is self._marker:
try:
result = self.context.get(name, self._marker)
except AttributeError:
pass
if result is self._marker:
raise TraversalError(name)
return result
def test_suite():
return unittest.TestSuite((
unittest.makeSuite( PluginRegistryExporterTests ),
unittest.makeSuite( PluginRegistryImporterTests ),
unittest.makeSuite( Test_exportPluginRegistry ),
unittest.makeSuite( Test_importPluginRegistry ),
))
if __name__ == '__main__':
unittest.main(defaultTest='test_suite')