Commit 8a3acd8e authored by Arnaud Fontaine's avatar Arnaud Fontaine

Implement migration of bt5 Document from filesystem to ZODB.

DocumentTemplateItem was renamed to FilesystemDocumentTemplateItem which will
be kept until the migration to Components is over. Also, move Extension
Component tests to its parent class (TestDocumentTemplateItem) to add tests
for bt5 Document.
parent 2f6e5176
......@@ -3327,7 +3327,9 @@ class ModuleTemplateItem(BaseTemplateItem):
# Do not remove any module for safety.
pass
class DocumentTemplateItem(BaseTemplateItem):
# XXX-arnau: when everything has been migrated to Components, everything in
# this class should be moved to DocumentTemplateItem
class FilesystemDocumentTemplateItem(BaseTemplateItem):
local_file_reader_name = staticmethod(readLocalDocument)
local_file_writer_name = staticmethod(writeLocalDocument)
local_file_importer_name = staticmethod(importLocalDocument)
......@@ -3400,7 +3402,7 @@ class DocumentTemplateItem(BaseTemplateItem):
update_dict = kw.get('object_to_update')
force = kw.get('force')
if context.getTemplateFormatVersion() == 1:
need_reset = isinstance(self, DocumentTemplateItem)
need_reset = isinstance(self, FilesystemDocumentTemplateItem)
for key in self._objects.keys():
# to achieve non data migration fresh installation parameters
# differ from upgrade parameteres, so here the check have to be
......@@ -3454,7 +3456,7 @@ class DocumentTemplateItem(BaseTemplateItem):
else:
object_keys = self._archive.keys()
if object_keys:
if isinstance(self, DocumentTemplateItem):
if isinstance(self, FilesystemDocumentTemplateItem):
self._resetDynamicModules()
for key in object_keys:
self.local_file_remover_name(key)
......@@ -3478,10 +3480,10 @@ class DocumentTemplateItem(BaseTemplateItem):
text = file.read()
self._objects[file_name[:-3]] = text
class FilesystemToZodbTemplateItem(DocumentTemplateItem,
class FilesystemToZodbTemplateItem(FilesystemDocumentTemplateItem,
ObjectTemplateItem):
"""
Abstract class to allow migration from DocumentTemplateItem to
Abstract class to allow migration from FilesystemDocumentTemplateItem to
ObjectTemplateItem, this is useful for migration from filesystem to ZODB for
PropertySheets and Components
"""
......@@ -3526,14 +3528,15 @@ class FilesystemToZodbTemplateItem(DocumentTemplateItem,
def _filesystemCompatibilityWrapper(method_name, object_dict_name):
"""
Call ObjectTemplateItem method when the objects have already been
migrated, otherwise fallback on DocumentTemplateItem method for
migrated, otherwise fallback on FilesystemDocumentTemplateItem method for
backward-compatibility
"""
def inner(self, *args, **kw):
if self._is_already_migrated(getattr(self, object_dict_name).keys()):
result = getattr(ObjectTemplateItem, method_name)(self, *args, **kw)
else:
result = getattr(DocumentTemplateItem, method_name)(self, *args, **kw)
result = getattr(FilesystemDocumentTemplateItem,
method_name)(self, *args, **kw)
return result
return inner
......@@ -3546,7 +3549,8 @@ class FilesystemToZodbTemplateItem(DocumentTemplateItem,
if file_name.endswith('.xml'):
return ObjectTemplateItem._importFile(self, file_name, *args, **kw)
else:
return DocumentTemplateItem._importFile(self, file_name, *args, **kw)
return FilesystemDocumentTemplateItem._importFile(self, file_name,
*args, **kw)
def uninstall(self, *args, **kw):
# Only for uninstall, the path of objects can be given as a
......@@ -3560,7 +3564,7 @@ class FilesystemToZodbTemplateItem(DocumentTemplateItem,
if self._is_already_migrated(object_keys):
return ObjectTemplateItem.uninstall(self, *args, **kw)
else:
return DocumentTemplateItem.uninstall(self, *args, **kw)
return FilesystemDocumentTemplateItem.uninstall(self, *args, **kw)
def remove(self, context, **kw):
"""
......@@ -3656,7 +3660,7 @@ class FilesystemToZodbTemplateItem(DocumentTemplateItem,
def install(self, context, **kw):
if not self._perform_migration:
return DocumentTemplateItem.install(self, context, **kw)
return FilesystemDocumentTemplateItem.install(self, context, **kw)
# With format 0 of Business Template, the objects are stored in
# '_archive' whereas they are stored in '_objects' with format
......@@ -3692,9 +3696,9 @@ class PropertySheetTemplateItem(FilesystemToZodbTemplateItem):
2/ The Property Sheets will all be migrated when installing the
Business Template.
Therefore, this is an all or nothing migration, meaning that only
methods of DocumentTemplateItem will be called before the migration
has been performed, then ObjectTemplateItem methods afterwards.
Therefore, this is an all or nothing migration, meaning that only methods of
FilesystemDocumentTemplateItem will be called before the migration has been
performed, then ObjectTemplateItem methods afterwards.
"""
# Only meaningful for filesystem Property Sheets
local_file_reader_name = staticmethod(readLocalPropertySheet)
......@@ -3744,16 +3748,16 @@ class PropertySheetTemplateItem(FilesystemToZodbTemplateItem):
return PropertySheetDocument.importFromFilesystemDefinition(tool, klass)
class ConstraintTemplateItem(DocumentTemplateItem):
class ConstraintTemplateItem(FilesystemDocumentTemplateItem):
local_file_reader_name = staticmethod(readLocalConstraint)
local_file_writer_name = staticmethod(writeLocalConstraint)
local_file_importer_name = staticmethod(importLocalConstraint)
local_file_remover_name = staticmethod(removeLocalConstraint)
from Products.ERP5Type.Core.ExtensionComponent import ExtensionComponent as \
ExtensionComponentDocument
from Products.ERP5Type.Core.DocumentComponent import DocumentComponent as \
DocumentComponentDocument
class ExtensionTemplateItem(FilesystemToZodbTemplateItem):
class DocumentTemplateItem(FilesystemToZodbTemplateItem):
"""
Extensions are now stored in ZODB rather than on the filesystem. However,
some Business Templates may still have filesystem Extensions which need to
......@@ -3764,12 +3768,16 @@ class ExtensionTemplateItem(FilesystemToZodbTemplateItem):
_tool_id = 'portal_components'
# Only meaningful for filesystem Extensions
local_file_reader_name = staticmethod(readLocalExtension)
local_file_writer_name = staticmethod(writeLocalExtension)
# Extension needs no import
local_file_importer_name = None
local_file_remover_name = staticmethod(removeLocalExtension)
@staticmethod
def _getZodbObjectId(id):
return 'erp5.component.document.%s' % id
@staticmethod
def _getFilesystemPath(class_id):
from App.config import getConfiguration
return os.path.join(getConfiguration().instancehome,
"Document",
"%s.py" % class_id)
def _importFile(self, file_name, file_obj):
if (file_name.endswith('.py') and
......@@ -3805,6 +3813,30 @@ class ExtensionTemplateItem(FilesystemToZodbTemplateItem):
XMLExportImport.exportXML(obj._p_jar, obj._p_oid, f)
bta.addObject(f, key, path=path)
@staticmethod
def _migrateFromFilesystem(tool,
filesystem_path,
filesystem_file,
class_id):
return DocumentComponentDocument.importFromFilesystem(tool,
filesystem_path)
from Products.ERP5Type.Core.ExtensionComponent import ExtensionComponent as \
ExtensionComponentDocument
class ExtensionTemplateItem(DocumentTemplateItem):
"""
Extensions are now stored in ZODB rather than on the filesystem. However,
some Business Templates may still have filesystem Extensions which need to
be migrated to the ZODB.
"""
# Only meaningful for filesystem Extensions
local_file_reader_name = staticmethod(readLocalExtension)
local_file_writer_name = staticmethod(writeLocalExtension)
# Extension needs no import
local_file_importer_name = None
local_file_remover_name = staticmethod(removeLocalExtension)
@staticmethod
def _getZodbObjectId(id):
return 'erp5.component.extension.%s' % id
......@@ -3824,7 +3856,7 @@ class ExtensionTemplateItem(FilesystemToZodbTemplateItem):
return ExtensionComponentDocument.importFromFilesystem(tool,
filesystem_path)
class TestTemplateItem(DocumentTemplateItem):
class TestTemplateItem(FilesystemDocumentTemplateItem):
local_file_reader_name = staticmethod(readLocalTest)
local_file_writer_name = staticmethod(writeLocalTest)
# Test needs no import
......
......@@ -6565,6 +6565,8 @@ class TestBusinessTemplate(BusinessTemplateMixin):
sequence_list.addSequenceString(sequence_string)
sequence_list.play(self)
from Products.ERP5Type.Core.DocumentComponent import DocumentComponent
class TestDocumentTemplateItem(BusinessTemplateMixin):
document_title = 'UnitTest'
document_data = """class UnitTest:
......@@ -6660,6 +6662,112 @@ class TestDocumentTemplateItem(BusinessTemplateMixin):
sequence_list.addSequenceString(sequence_string)
sequence_list.play(self)
component_module = DocumentComponent._getDynamicModuleNamespace()
component_portal_type = DocumentComponent.portal_type
def getBusinessTemplateList(self):
return (super(TestDocumentTemplateItem, self).getBusinessTemplateList() +
('erp5_core_component',))
def stepCheckZodbDocumentRemoved(self, sequence=None, **kw):
component_tool = self.getPortalObject().portal_components
component_id = '%s.%s' % (self.component_module, sequence['document_title'])
self.failIf(component_id in component_tool.objectIds())
def stepRemoveZodbDocument(self, sequence=None, **kw):
"""
Remove Property Sheet, but only from ZODB
"""
component_id = '%s.%s' % (self.component_module, sequence['document_title'])
self.portal.portal_components.manage_delObjects([component_id])
def stepCheckDocumentMigration(self, sequence=None, **kw):
"""
Check migration of Document from the Filesystem to ZODB
"""
component_id = '%s.%s' % (self.component_module, sequence['document_title'])
component_tool = self.getPortalObject().portal_components
self.failUnless(component_id in component_tool.objectIds())
component = getattr(component_tool, component_id)
self.assertEquals(component.getReference(), self.document_title)
self.assertEquals(component.getTextContent(), self.document_data)
self.assertEquals(component.getPortalType(), self.component_portal_type)
def stepCheckForkedMigrationExport(self, sequence=None, **kw):
component_bt_tool_path = os.path.join(sequence['template_path'],
self.__class__.__name__.replace('Test', ''),
'portal_components')
self.assertTrue(os.path.exists(component_bt_tool_path))
component_id = '%s.%s' % (self.component_module, sequence['document_title'])
base_path = os.path.join(component_bt_tool_path, component_id)
python_source_code_path = base_path + '.py'
self.assertTrue(os.path.exists(python_source_code_path))
source_code = sequence['document_data']
with open(python_source_code_path) as f:
self.assertEquals(f.read(), source_code)
xml_path = base_path + '.xml'
self.assertTrue(os.path.exists(xml_path))
first_line = source_code.split('\n', 1)[0]
with open(xml_path) as f:
for line in f:
self.failIf(first_line in line)
def test_BusinessTemplateWithDocumentMigration(self):
sequence_list = SequenceList()
sequence_string = '\
CreateDocument \
CreateNewBusinessTemplate \
UseExportBusinessTemplate \
AddDocumentToBusinessTemplate \
CheckModifiedBuildingState \
CheckNotInstalledInstallationState \
BuildBusinessTemplate \
CheckBuiltBuildingState \
CheckNotInstalledInstallationState \
CheckObjectPropertiesInBusinessTemplate \
SaveBusinessTemplate \
CheckBuiltBuildingState \
CheckNotInstalledInstallationState \
RemoveDocument \
RemoveBusinessTemplate \
RemoveAllTrashBins \
ImportBusinessTemplate \
UseImportBusinessTemplate \
CheckBuiltBuildingState \
CheckNotInstalledInstallationState \
InstallWithoutForceBusinessTemplate \
Tic \
CheckInstalledInstallationState \
CheckBuiltBuildingState \
CheckNoTrashBin \
CheckSkinsLayers \
CheckDocumentMigration \
CheckDocumentRemoved \
UninstallBusinessTemplate \
CheckBuiltBuildingState \
CheckNotInstalledInstallationState \
CheckZodbDocumentRemoved \
SaveBusinessTemplate \
CheckForkedMigrationExport \
'
sequence_list.addSequenceString(sequence_string)
# XXX-arnau: Temporary until _perform_migration is set to True by default
from Products.ERP5.Document.BusinessTemplate import DocumentTemplateItem
DocumentTemplateItem._perform_migration = True
try:
sequence_list.play(self)
finally:
DocumentTemplateItem._perform_migration = False
def test_BusinessTemplateUpdateWithDocument(self):
sequence_list = SequenceList()
sequence_string = '\
......@@ -6887,109 +6995,6 @@ class TestExtensionTemplateItem(TestDocumentTemplateItem):
component_module = ExtensionComponent._getDynamicModuleNamespace()
component_portal_type = ExtensionComponent.portal_type
def getBusinessTemplateList(self):
return (super(TestExtensionTemplateItem, self).getBusinessTemplateList() +
('erp5_core_component',))
def stepCheckZodbDocumentRemoved(self, sequence=None, **kw):
component_tool = self.getPortalObject().portal_components
component_id = 'erp5.component.extension.' + sequence['document_title']
self.failIf(component_id in component_tool.objectIds())
def stepRemoveZodbDocument(self, sequence=None, **kw):
"""
Remove Property Sheet, but only from ZODB
"""
component_id = '%s.%s' % (self.component_module, sequence['document_title'])
self.portal.portal_components.manage_delObjects([component_id])
def stepCheckDocumentMigration(self, sequence=None, **kw):
"""
Check migration of Document from the Filesystem to ZODB
"""
component_id = '%s.%s' % (self.component_module, sequence['document_title'])
component_tool = self.getPortalObject().portal_components
self.failUnless(component_id in component_tool.objectIds())
component = getattr(component_tool, component_id)
self.assertEquals(component.getReference(), self.document_title)
self.assertEquals(component.getTextContent(), self.document_data)
self.assertEquals(component.getPortalType(), self.component_portal_type)
def stepCheckForkedMigrationExport(self, sequence=None, **kw):
component_bt_tool_path = os.path.join(sequence['template_path'],
'ExtensionTemplateItem',
'portal_components')
self.assertTrue(os.path.exists(component_bt_tool_path))
component_id = '%s.%s' % (self.component_module, sequence['document_title'])
base_path = os.path.join(component_bt_tool_path, component_id)
python_source_code_path = base_path + '.py'
self.assertTrue(os.path.exists(python_source_code_path))
source_code = sequence['document_data']
with open(python_source_code_path) as f:
self.assertEquals(f.read(), source_code)
xml_path = base_path + '.xml'
self.assertTrue(os.path.exists(xml_path))
first_line = source_code.split('\n', 1)[0]
with open(xml_path) as f:
for line in f:
self.failIf(first_line in line)
def test_BusinessTemplateWithDocumentMigration(self):
sequence_list = SequenceList()
sequence_string = '\
CreateDocument \
CreateNewBusinessTemplate \
UseExportBusinessTemplate \
AddDocumentToBusinessTemplate \
CheckModifiedBuildingState \
CheckNotInstalledInstallationState \
BuildBusinessTemplate \
CheckBuiltBuildingState \
CheckNotInstalledInstallationState \
CheckObjectPropertiesInBusinessTemplate \
SaveBusinessTemplate \
CheckBuiltBuildingState \
CheckNotInstalledInstallationState \
RemoveDocument \
RemoveBusinessTemplate \
RemoveAllTrashBins \
ImportBusinessTemplate \
UseImportBusinessTemplate \
CheckBuiltBuildingState \
CheckNotInstalledInstallationState \
InstallWithoutForceBusinessTemplate \
Tic \
CheckInstalledInstallationState \
CheckBuiltBuildingState \
CheckNoTrashBin \
CheckSkinsLayers \
CheckDocumentMigration \
CheckDocumentRemoved \
UninstallBusinessTemplate \
CheckBuiltBuildingState \
CheckNotInstalledInstallationState \
CheckZodbDocumentRemoved \
SaveBusinessTemplate \
CheckForkedMigrationExport \
'
sequence_list.addSequenceString(sequence_string)
# XXX-arnau: Temporary until _perform_migration is set to True by default
from Products.ERP5.Document.BusinessTemplate import ExtensionTemplateItem
ExtensionTemplateItem._perform_migration = True
try:
sequence_list.play(self)
finally:
ExtensionTemplateItem._perform_migration = False
class TestTestTemplateItem(TestDocumentTemplateItem):
document_title = 'UnitTest'
document_data = """class UnitTest:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment