Back to index

plone3  3.1.7
test_exportimport.py
Go to the documentation of this file.
00001 ##############################################################################
00002 #
00003 # Copyright (c) 2005 Zope Corporation and Contributors. All Rights
00004 # Reserved.
00005 #
00006 # This software is subject to the provisions of the Zope Public License,
00007 # Version 2.0 (ZPL).  A copy of the ZPL should accompany this
00008 # distribution.
00009 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
00010 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00011 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
00012 # FOR A PARTICULAR PURPOSE
00013 #
00014 ##############################################################################
00015 """ Unit tests for GenericSetup-based export / import of PluginRegistry.
00016 
00017 $Id: test_exportimport.py 74716 2007-04-24 19:15:04Z tseaver $
00018 """
00019 import unittest
00020 
00021 try:
00022     import Products.GenericSetup
00023 except ImportError:  # No GenericSetup, so no tests
00024 
00025     print 'XXXX:  No GenericSetup!'
00026     def test_suite():
00027         return unittest.TestSuite()
00028 
00029 else:
00030     from Products.GenericSetup.tests.common import BaseRegistryTests
00031     from Products.GenericSetup.tests.common import DummyExportContext
00032     from Products.GenericSetup.tests.common import DummyImportContext
00033     from Products.GenericSetup.utils import _getDottedName
00034 
00035     from zope.interface import Interface
00036     from zope.interface import directlyProvides
00037     from zope.app.testing import ztapi
00038 
00039     try:
00040         from zope.traversing.interfaces import ITraversable
00041         from zope.traversing.interfaces import TraversalError
00042     except ImportError:
00043         # BBB for Zope 2.9
00044         from zope.app.traversing.interfaces import ITraversable
00045         from zope.app.traversing.interfaces import TraversalError
00046 
00047     try:
00048         from zope.app.testing.placelesssetup import PlacelessSetup
00049     except ImportError:
00050         # BBB for Zope 2.8
00051         from zope.app.tests.placelesssetup import PlacelessSetup
00052 
00053     class IFoo(Interface):
00054         pass
00055 
00056     class IBar(Interface):
00057         pass
00058 
00059     _EMPTY_PLUGINREGISTRY_EXPORT = """\
00060 <?xml version="1.0"?>
00061 <plugin-registry>
00062 </plugin-registry>
00063 """
00064 
00065     _PLUGIN_TYPE_INFO = (
00066       ( IFoo
00067       , 'IFoo'
00068       , 'foo'
00069       , "Some plugin interface"
00070       )
00071     , ( IBar
00072       , 'IBar'
00073       , 'bar'
00074       , "Another plugin interface"
00075       )
00076     )
00077 
00078     _NO_PLUGINS_PLUGINREGISTRY_EXPORT = """\
00079 <?xml version="1.0"?>
00080 <plugin-registry>
00081  <plugin-type
00082     id="IFoo"
00083     interface="%s"
00084     title="foo"
00085     description="Some plugin interface">
00086  </plugin-type>
00087  <plugin-type
00088     id="IBar"
00089     interface="%s"
00090     title="bar"
00091     description="Another plugin interface">
00092  </plugin-type>
00093 </plugin-registry>
00094 """ % (_getDottedName(IFoo), _getDottedName(IBar))
00095 
00096     _NORMAL_PLUGINREGISTRY_EXPORT = """\
00097 <?xml version="1.0"?>
00098 <plugin-registry>
00099  <plugin-type
00100     id="IFoo"
00101     interface="%s"
00102     title="foo"
00103     description="Some plugin interface">
00104   <plugin id="foo_plugin_1" />
00105   <plugin id="foo_plugin_2" />
00106  </plugin-type>
00107  <plugin-type
00108     id="IBar"
00109     interface="%s"
00110     title="bar"
00111     description="Another plugin interface">
00112  </plugin-type>
00113 </plugin-registry>
00114 """ % (_getDottedName(IFoo), _getDottedName(IBar))
00115 
00116     class _TestBase(PlacelessSetup, BaseRegistryTests):
00117 
00118         def _initRegistry(self, plugin_type_info=(), plugins={}):
00119             from OFS.Folder import Folder
00120             from OFS.SimpleItem import SimpleItem
00121             from Products.PluginRegistry.PluginRegistry import PluginRegistry
00122 
00123             app = Folder()
00124             app.getPhysicalPath = lambda: ()
00125             app.getPhysicalRoot = lambda: app
00126 
00127             app._setObject('foo_plugin_1', SimpleItem())
00128             app._setObject('foo_plugin_2', SimpleItem())
00129 
00130             registry = PluginRegistry(plugin_type_info)
00131             registry._plugins = {} # it is usually lazy
00132 
00133             for plugin_type, registered in plugins.items():
00134                 for obj_id in registered:
00135                     obj = app._getOb(obj_id)
00136                     directlyProvides(obj, plugin_type)
00137                 registry._plugins[plugin_type] = registered
00138 
00139             app._setObject('plugin_registry', registry)
00140             registry = app._getOb('plugin_registry')
00141             return app, registry
00142 
00143     class PluginRegistryExporterTests(_TestBase):
00144 
00145         def _getTargetClass(self):
00146             from Products.PluginRegistry.exportimport \
00147                 import PluginRegistryExporter
00148             return PluginRegistryExporter
00149 
00150         def test_empty(self):
00151             ztapi.provideAdapter(None, ITraversable, AttrItemTraverser)
00152 
00153             app, registry = self._initRegistry()
00154             exporter = self._makeOne(registry).__of__(registry)
00155             xml = exporter.generateXML()
00156 
00157             self._compareDOM(xml, _EMPTY_PLUGINREGISTRY_EXPORT)
00158 
00159         def test_normal_no_plugins(self):
00160             ztapi.provideAdapter(None, ITraversable, AttrItemTraverser)
00161 
00162             app, registry = self._initRegistry(
00163                                     plugin_type_info=_PLUGIN_TYPE_INFO)
00164             exporter = self._makeOne(registry).__of__(registry)
00165             xml = exporter.generateXML()
00166 
00167             self._compareDOM(xml, _NO_PLUGINS_PLUGINREGISTRY_EXPORT)
00168 
00169         def test_normal_with_plugins(self):
00170             ztapi.provideAdapter(None, ITraversable, AttrItemTraverser)
00171 
00172             app, registry = self._initRegistry(
00173                                     plugin_type_info=_PLUGIN_TYPE_INFO,
00174                                     plugins={IFoo: ('foo_plugin_1',
00175                                                     'foo_plugin_2')},
00176                                         )
00177             exporter = self._makeOne(registry).__of__(registry)
00178             xml = exporter.generateXML()
00179 
00180             self._compareDOM(xml, _NORMAL_PLUGINREGISTRY_EXPORT)
00181 
00182     class Test_exportPluginRegistry(_TestBase):
00183 
00184         def test_empty(self):
00185             from Products.PluginRegistry.exportimport \
00186                 import exportPluginRegistry
00187             ztapi.provideAdapter(None, ITraversable, AttrItemTraverser)
00188 
00189             app, registry = self._initRegistry()
00190             context = DummyExportContext(app)
00191             exportPluginRegistry(context)
00192 
00193             self.assertEqual( len(context._wrote), 1 )
00194             filename, text, content_type = context._wrote[0]
00195             self.assertEqual(filename, 'pluginregistry.xml')
00196             self._compareDOM(text, _EMPTY_PLUGINREGISTRY_EXPORT)
00197             self.assertEqual(content_type, 'text/xml')
00198 
00199         def test_normal_no_plugins(self):
00200             from Products.PluginRegistry.exportimport \
00201                 import exportPluginRegistry
00202             ztapi.provideAdapter(None, ITraversable, AttrItemTraverser)
00203 
00204             app, registry = self._initRegistry(
00205                                     plugin_type_info=_PLUGIN_TYPE_INFO)
00206             context = DummyExportContext(app)
00207             exportPluginRegistry(context)
00208 
00209             self.assertEqual( len(context._wrote), 1 )
00210             filename, text, content_type = context._wrote[0]
00211             self.assertEqual(filename, 'pluginregistry.xml')
00212             self._compareDOM(text, _NO_PLUGINS_PLUGINREGISTRY_EXPORT)
00213             self.assertEqual(content_type, 'text/xml')
00214 
00215         def test_normal_with_plugins(self):
00216             from Products.PluginRegistry.exportimport \
00217                 import exportPluginRegistry
00218             ztapi.provideAdapter(None, ITraversable, AttrItemTraverser)
00219 
00220             app, registry = self._initRegistry(
00221                                     plugin_type_info=_PLUGIN_TYPE_INFO,
00222                                     plugins={IFoo: ('foo_plugin_1',
00223                                                     'foo_plugin_2')},
00224                                         )
00225             context = DummyExportContext(app)
00226             exportPluginRegistry(context)
00227 
00228             self.assertEqual( len(context._wrote), 1 )
00229             filename, text, content_type = context._wrote[0]
00230             self.assertEqual(filename, 'pluginregistry.xml')
00231             self._compareDOM(text, _NORMAL_PLUGINREGISTRY_EXPORT)
00232             self.assertEqual(content_type, 'text/xml')
00233 
00234     class PluginRegistryImporterTests(_TestBase):
00235 
00236         def _getTargetClass(self):
00237             from Products.PluginRegistry.exportimport \
00238                 import PluginRegistryImporter
00239             return PluginRegistryImporter
00240 
00241         def test_parseXML_empty(self):
00242 
00243             app, registry = self._initRegistry()
00244             importer = self._makeOne(registry).__of__(registry)
00245             reg_info = importer.parseXML(_EMPTY_PLUGINREGISTRY_EXPORT)
00246 
00247             self.assertEqual( len( reg_info['plugin_types'] ), 0 )
00248 
00249         def test_parseXML_normal_no_plugins(self):
00250 
00251             app, registry = self._initRegistry()
00252             importer = self._makeOne(registry).__of__(registry)
00253             reg_info = importer.parseXML(_NO_PLUGINS_PLUGINREGISTRY_EXPORT)
00254 
00255             self.assertEqual( len( reg_info['plugin_types'] ), 2 )
00256 
00257             info = reg_info['plugin_types'][0]
00258             self.assertEqual(info['id'], 'IFoo')
00259             self.assertEqual(info['interface'], _getDottedName(IFoo))
00260             self.assertEqual(info['title'], 'foo')
00261             self.assertEqual(info['description'], 'Some plugin interface')
00262             self.assertEqual(len( info['plugins'] ), 0)
00263 
00264             info = reg_info['plugin_types'][1]
00265             self.assertEqual(info['id'], 'IBar')
00266             self.assertEqual(info['interface'], _getDottedName(IBar))
00267             self.assertEqual(info['title'], 'bar')
00268             self.assertEqual(info['description'], 'Another plugin interface')
00269             self.assertEqual(len( info['plugins'] ), 0 )
00270 
00271         def test_parseXML_normal_with_plugins(self):
00272 
00273             app, registry = self._initRegistry()
00274             importer = self._makeOne(registry).__of__(registry)
00275             reg_info = importer.parseXML(_NORMAL_PLUGINREGISTRY_EXPORT)
00276 
00277             self.assertEqual(len(reg_info['plugin_types'] ), 2 )
00278 
00279             info = reg_info['plugin_types'][0]
00280             self.assertEqual(info['id'], 'IFoo')
00281             self.assertEqual(info['interface'], _getDottedName(IFoo))
00282             self.assertEqual(info['title'], 'foo')
00283             self.assertEqual(info['description'], 'Some plugin interface')
00284             plugins = info['plugins']
00285             self.assertEqual(len(plugins), 2)
00286             self.assertEqual(plugins[0]['id'], 'foo_plugin_1')
00287             self.assertEqual(plugins[1]['id'], 'foo_plugin_2')
00288 
00289             info = reg_info['plugin_types'][1]
00290             self.assertEqual(info['id'], 'IBar')
00291             self.assertEqual(info['interface'], _getDottedName(IBar))
00292             self.assertEqual(info['title'], 'bar')
00293             self.assertEqual(info['description'], 'Another plugin interface')
00294             self.assertEqual(len(info['plugins']), 0 )
00295 
00296     class Test_importPluginRegistry(_TestBase):
00297 
00298         def test_empty_default_purge(self):
00299             from Products.PluginRegistry.exportimport \
00300                 import importPluginRegistry
00301 
00302             app, registry = self._initRegistry(
00303                                     plugin_type_info=_PLUGIN_TYPE_INFO,
00304                                     plugins={IFoo: ('foo_plugin_1',
00305                                                     'foo_plugin_2')},
00306                                    )
00307 
00308             self.assertEqual(len(registry.listPluginTypeInfo()), 2)
00309             self.assertEqual(len(registry.listPlugins(IFoo)), 2)
00310             self.assertEqual(len(registry.listPlugins(IBar)), 0)
00311 
00312             context = DummyImportContext(app)
00313             context._files['pluginregistry.xml'] = _EMPTY_PLUGINREGISTRY_EXPORT
00314 
00315             importPluginRegistry(context)
00316 
00317             self.assertEqual(len(registry.listPluginTypeInfo()), 0)
00318             self.assertRaises(KeyError, registry.listPlugins, IFoo)
00319             self.assertRaises(KeyError, registry.listPlugins, IBar)
00320 
00321         def test_empty_explicit_purge(self):
00322             from Products.PluginRegistry.exportimport \
00323                 import importPluginRegistry
00324 
00325             app, registry = self._initRegistry(
00326                                     plugin_type_info=_PLUGIN_TYPE_INFO,
00327                                     plugins={IFoo: ('foo_plugin_1',
00328                                                     'foo_plugin_2')},
00329                                    )
00330 
00331             self.assertEqual(len(registry.listPluginTypeInfo()), 2)
00332             self.assertEqual(len(registry.listPlugins(IFoo)), 2)
00333             self.assertEqual(len(registry.listPlugins(IBar)), 0)
00334 
00335             context = DummyImportContext(app, True)
00336             context._files['pluginregistry.xml'] = _EMPTY_PLUGINREGISTRY_EXPORT
00337 
00338             importPluginRegistry(context)
00339 
00340             self.assertEqual(len(registry.listPluginTypeInfo()), 0)
00341             self.assertRaises(KeyError, registry.listPlugins, IFoo)
00342             self.assertRaises(KeyError, registry.listPlugins, IBar)
00343 
00344         def test_empty_skip_purge(self):
00345             from Products.PluginRegistry.exportimport \
00346                 import importPluginRegistry
00347 
00348             app, registry = self._initRegistry(
00349                                     plugin_type_info=_PLUGIN_TYPE_INFO,
00350                                     plugins={IFoo: ('foo_plugin_1',
00351                                                     'foo_plugin_2')},
00352                                    )
00353 
00354             self.assertEqual(len(registry.listPluginTypeInfo()), 2)
00355             self.assertEqual(len(registry.listPlugins(IFoo)), 2)
00356             self.assertEqual(len(registry.listPlugins(IBar)), 0)
00357 
00358             context = DummyImportContext(app, False)
00359             context._files['pluginregistry.xml'] = _EMPTY_PLUGINREGISTRY_EXPORT
00360 
00361             importPluginRegistry(context)
00362 
00363             self.assertEqual(len(registry.listPluginTypeInfo()), 2)
00364             self.assertEqual(len(registry.listPlugins(IFoo)), 2)
00365             self.assertEqual(len(registry.listPlugins(IBar)), 0)
00366 
00367         def test_normal_no_plugins(self):
00368             from Products.PluginRegistry.exportimport \
00369                 import importPluginRegistry
00370 
00371             app, registry = self._initRegistry(plugins={IFoo: ('foo_plugin_1',
00372                                                                'foo_plugin_2')},
00373                                               )
00374 
00375             self.assertEqual(len(registry.listPluginTypeInfo()), 0)
00376             self.assertRaises(KeyError, registry.listPlugins, IFoo)
00377             self.assertRaises(KeyError, registry.listPlugins, IBar)
00378 
00379             context = DummyImportContext(app, False)
00380             context._files['pluginregistry.xml'
00381                           ] = _NO_PLUGINS_PLUGINREGISTRY_EXPORT
00382 
00383             importPluginRegistry(context)
00384 
00385             self.assertEqual(len(registry.listPluginTypeInfo()), 2)
00386 
00387             info = registry.listPluginTypeInfo()[0]
00388             self.assertEqual(info['id'], 'IFoo')
00389             self.assertEqual(info['title'], 'foo')
00390             self.assertEqual(info['description'], 'Some plugin interface')
00391 
00392             info = registry.listPluginTypeInfo()[1]
00393             self.assertEqual(info['id'], 'IBar')
00394             self.assertEqual(info['title'], 'bar')
00395             self.assertEqual(info['description'], 'Another plugin interface')
00396 
00397             self.assertEqual(len(registry.listPlugins(IFoo)), 0)
00398             self.assertEqual(len(registry.listPlugins(IBar)), 0)
00399 
00400         def test_normal_with_plugins(self):
00401             from Products.PluginRegistry.exportimport \
00402                 import importPluginRegistry
00403 
00404             app, registry = self._initRegistry(plugins={IFoo: ('foo_plugin_1',
00405                                                                'foo_plugin_2')},
00406                                               )
00407 
00408             self.assertEqual(len(registry.listPluginTypeInfo()), 0)
00409             self.assertRaises(KeyError, registry.listPlugins, IFoo)
00410             self.assertRaises(KeyError, registry.listPlugins, IBar)
00411 
00412             context = DummyImportContext(app, False)
00413             context._files['pluginregistry.xml'
00414                           ] = _NORMAL_PLUGINREGISTRY_EXPORT
00415 
00416             importPluginRegistry(context)
00417 
00418             self.assertEqual(len(registry.listPluginTypeInfo()), 2)
00419 
00420             info = registry.listPluginTypeInfo()[0]
00421             self.assertEqual(info['id'], 'IFoo')
00422             self.assertEqual(info['title'], 'foo')
00423             self.assertEqual(info['description'], 'Some plugin interface')
00424 
00425             info = registry.listPluginTypeInfo()[1]
00426             self.assertEqual(info['id'], 'IBar')
00427             self.assertEqual(info['title'], 'bar')
00428             self.assertEqual(info['description'], 'Another plugin interface')
00429 
00430             self.assertEqual(len(registry.listPlugins(IFoo)), 2)
00431             plugins = registry.listPlugins(IFoo)
00432             self.assertEqual(plugins[0][0], 'foo_plugin_1')
00433             self.assertEqual(plugins[0][1], app._getOb('foo_plugin_1'))
00434             self.assertEqual(plugins[1][0], 'foo_plugin_2')
00435             self.assertEqual(plugins[1][1], app._getOb('foo_plugin_2'))
00436 
00437             self.assertEqual(len(registry.listPlugins(IBar)), 0)
00438 
00439         def test_normal_with_plugins_skip_duplicates(self):
00440             # See http://www.zope.org/Collectors/PAS/52
00441             from Products.PluginRegistry.exportimport \
00442                 import importPluginRegistry
00443 
00444             app, registry = self._initRegistry()
00445 
00446             self.assertEqual(len(registry.listPluginTypeInfo()), 0)
00447             self.assertRaises(KeyError, registry.listPlugins, IFoo)
00448             self.assertRaises(KeyError, registry.listPlugins, IBar)
00449 
00450             context = DummyImportContext(app, False)
00451             context._files['pluginregistry.xml'
00452                           ] = _NORMAL_PLUGINREGISTRY_EXPORT
00453 
00454             importPluginRegistry(context)
00455             importPluginRegistry(context) # twice should not duplicate
00456 
00457             self.assertEqual(len(registry.listPluginTypeInfo()), 2)
00458 
00459     class AttrItemTraverser:
00460         _marker = object()
00461 
00462         def __init__(self, context):
00463             self.context = context
00464 
00465         def traverse(self, name, furtherPath):
00466             result = getattr(self.context, name, self._marker)
00467             if result is self._marker:
00468                 try:
00469                     result = self.context.get(name, self._marker)
00470                 except AttributeError:
00471                     pass
00472             if result is self._marker:
00473                 raise TraversalError(name)
00474             return result
00475 
00476     def test_suite():
00477         return unittest.TestSuite((
00478             unittest.makeSuite( PluginRegistryExporterTests ),
00479             unittest.makeSuite( PluginRegistryImporterTests ),
00480             unittest.makeSuite( Test_exportPluginRegistry ),
00481             unittest.makeSuite( Test_importPluginRegistry ),
00482            ))
00483 
00484 if __name__ == '__main__':
00485     unittest.main(defaultTest='test_suite')
00486