[Testbot] Plone 4.3 - Python 2.6 - Build # 2652 - Still failing! - 0 failure(s)
jenkins at plone.org
jenkins at plone.org
Tue Jan 27 17:41:14 UTC 2015
-------------------------------------------------------------------------------
Plone 4.3 - Python 2.6 - Build # 2652 - Still Failing!
-------------------------------------------------------------------------------
http://jenkins.plone.org/job/plone-4.3-python-2.6/2652/
-------------------------------------------------------------------------------
CHANGES
-------------------------------------------------------------------------------
Repository: plone.app.contenttypes
Branch: refs/heads/1.1.x
Date: 2015-01-27T17:42:02+01:00
Author: Philip Bauer (pbauer) <bauer at starzel.de>
Commit: https://github.com/plone/plone.app.contenttypes/commit/000a1c799a2ac0d4b2617a4c04df563cbd594452
reuse patch-method from Products.contentmigration.utils
Prevent UUID Error-Messages when migrating folders.
Files changed:
A plone/app/contenttypes/migration/patches.py
M plone/app/contenttypes/migration/browser.py
diff --git a/plone/app/contenttypes/migration/browser.py b/plone/app/contenttypes/migration/browser.py
index 4b9beff..77b8c09 100644
--- a/plone/app/contenttypes/migration/browser.py
+++ b/plone/app/contenttypes/migration/browser.py
@@ -6,6 +6,7 @@
from Products.CMFPlone import PloneMessageFactory as _
from Products.Five.browser import BrowserView
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
+from Products.contentmigration.utils import patch, undoPatch
from Products.statusmessages.interfaces import IStatusMessage
from datetime import datetime
from datetime import timedelta
@@ -17,6 +18,7 @@
from plone.app.contenttypes.content import NewsItem
from plone.app.contenttypes.migration import dxmigration
from plone.app.contenttypes.migration import migration
+from plone.app.contenttypes.migration.patches import patched_insertForwardIndexEntry
from plone.app.contenttypes.migration.utils import HAS_MULTILINGUAL
from plone.app.contenttypes.migration.utils import installTypeIfNeeded
from plone.app.contenttypes.migration.utils import isSchemaExtended
@@ -37,6 +39,7 @@
from zope.component import getMultiAdapter
from zope.component import queryUtility
from zope.interface import Interface
+from Products.PluginIndexes.UUIDIndex.UUIDIndex import UUIDIndex
import logging
import pkg_resources
@@ -61,6 +64,11 @@
ONE_OBJECT_MIGRATION_TIME = 500
+def pass_fn(*args, **kwargs):
+ """Empty function used for patching."""
+ pass
+
+
class FixBaseClasses(BrowserView):
def __call__(self):
@@ -113,6 +121,9 @@ def __call__(self,
from_form=False):
portal = self.context
+ if content_types == 'all':
+ content_types = DEFAULT_TYPES
+
if not from_form and migrate not in ['1', 'True', 'true', 1]:
url1 = '{0}/@@migrate_from_atct?migrate=1'.format(
portal.absolute_url())
@@ -149,11 +160,17 @@ def __call__(self,
# switch of setModificationDate on changes
self.patchNotifyModified()
+ # patch UUIDIndex
+ patch(
+ UUIDIndex,
+ 'insertForwardIndexEntry',
+ patched_insertForwardIndexEntry)
+
not_migrated = []
migrated_types = {}
for (k, v) in ATCT_LIST.items():
- if content_types != "all" and k not in content_types:
+ if k not in content_types:
not_migrated.append(k)
continue
# test if the ct is extended beyond blobimage and blobfile
@@ -207,6 +224,9 @@ def __call__(self,
# switch on setModificationDate on changes
self.resetNotifyModified()
+ # unpatch UUIDIndex
+ undoPatch(UUIDIndex, 'insertForwardIndexEntry')
+
duration = str(timedelta(seconds=(datetime.now() - starttime).seconds))
if not_migrated:
msg = ("The following types were not migrated: \n %s"
@@ -257,21 +277,13 @@ def patchNotifyModified(self):
So when we migrate Documents before Folders the folders
ModifiedDate gets changed.
"""
- patch = lambda *args: None
for klass in PATCH_NOTIFY:
- old_notifyModified = getattr(klass, 'notifyModified', None)
- klass.notifyModified = patch
- klass.old_notifyModified = old_notifyModified
+ patch(klass, 'notifyModified', pass_fn)
def resetNotifyModified(self):
"""reset notifyModified to old state"""
-
for klass in PATCH_NOTIFY:
- if klass.old_notifyModified is None:
- del klass.notifyModified
- else:
- klass.notifyModified = klass.old_notifyModified
- del klass.old_notifyModified
+ undoPatch(klass, 'notifyModified')
class IATCTMigratorForm(Interface):
diff --git a/plone/app/contenttypes/migration/patches.py b/plone/app/contenttypes/migration/patches.py
new file mode 100644
index 0000000..30ecc88
--- /dev/null
+++ b/plone/app/contenttypes/migration/patches.py
@@ -0,0 +1,23 @@
+# -*- coding: UTF-8 -*-
+"""Patches used for migrations. These patches are applied before and removed
+after running the migration.
+"""
+from Products.PluginIndexes.common.UnIndex import _marker
+
+
+# Prevent UUID Error-Messages when migrating folders.
+# Products.PluginIndexes.UUIDIndex.UUIDIndex.UUIDIndex.insertForwardIndexEntry
+def patched_insertForwardIndexEntry(self, entry, documentId):
+ """Take the entry provided and put it in the correct place
+ in the forward index.
+ """
+ if entry is None:
+ return
+
+ old_docid = self._index.get(entry, _marker)
+ if old_docid is _marker:
+ self._index[entry] = documentId
+ self._length.change(1)
+ # elif old_docid != documentId:
+ # logger.error("A different document with value '%s' already "
+ # "exists in the index.'" % entry)
Repository: plone.app.contenttypes
Branch: refs/heads/1.1.x
Date: 2015-01-27T17:44:53+01:00
Author: Philip Bauer (pbauer) <bauer at starzel.de>
Commit: https://github.com/plone/plone.app.contenttypes/commit/c50b9a11a09ab0677280c0769a86b0e10129758f
always rebuild catalog after migrating
refactor restoreReferences
Files changed:
M plone/app/contenttypes/migration/browser.py
M plone/app/contenttypes/migration/migration.py
M plone/app/contenttypes/tests/test_migration.py
diff --git a/plone/app/contenttypes/migration/browser.py b/plone/app/contenttypes/migration/browser.py
index 77b8c09..be37bd3 100644
--- a/plone/app/contenttypes/migration/browser.py
+++ b/plone/app/contenttypes/migration/browser.py
@@ -213,8 +213,10 @@ def __call__(self,
# if there are blobnewsitems we just migrate them silently.
migration.migrate_blobnewsitems(portal)
- if migrate_references:
- migration.restoreReferences(portal)
+ catalog.clearFindAndRebuild()
+
+ # rebuild catalog, restore references and cleanup
+ migration.restoreReferences(portal, migrate_references, content_types)
# switch linkintegrity back to what it was before migrating
site_props.manage_changeProperties(
@@ -300,10 +302,7 @@ class IATCTMigratorForm(Interface):
migrate_references = schema.Bool(
title=u"Migrate references?",
description=(
- u"Select this option to migrate all "
- u"references to each content type. "
- u"This will rebuild the whole catalog and "
- u"increase the migration-time."
+ u"Select this option to migrate references."
),
default=True
)
diff --git a/plone/app/contenttypes/migration/migration.py b/plone/app/contenttypes/migration/migration.py
index 5c171c5..1579531 100644
--- a/plone/app/contenttypes/migration/migration.py
+++ b/plone/app/contenttypes/migration/migration.py
@@ -24,6 +24,7 @@
from plone.app.contenttypes.migration.utils import copy_contentrules
from plone.app.contenttypes.migration.utils import move_comments
from plone.app.contenttypes.migration.utils import migrate_leadimage
+from plone.app.contenttypes.utils import DEFAULT_TYPES
from plone.app.textfield.value import RichTextValue
from plone.app.uuid.utils import uuidToObject
from plone.dexterity.interfaces import IDexterityContent
@@ -90,10 +91,10 @@ def migrate_portlets(src_obj, dst_obj):
'for manager {1}'.format(key, manager))
-def refs(obj):
+def restore_refs(obj):
+ """Restore references stored in the attribute _relatedItems.
+ """
intids = getUtility(IIntIds)
- out = ''
-
try:
if not getattr(obj, 'relatedItems', None):
obj.relatedItems = PersistentList()
@@ -105,19 +106,16 @@ def refs(obj):
to_obj = uuidToObject(uuid)
to_id = intids.getId(to_obj)
obj.relatedItems.append(RelationValue(to_id))
- out += str('Restore Relation from %s to %s \n' % (obj, to_obj))
- del obj._relatedItems
-
+ logger.info('Restored Relation from %s to %s' % (obj, to_obj))
except AttributeError:
pass
- return out
-def backrefs(portal, obj):
+def restore_backrefs(portal, obj):
+ """Restore backreferences stored in the attribute _backrefs.
+ """
intids = getUtility(IIntIds)
uid_catalog = getToolByName(portal, 'uid_catalog')
- out = ''
-
try:
backrefobjs = [uuidToObject(uuid) for uuid in obj._backrefs]
for backrefobj in backrefobjs:
@@ -139,53 +137,51 @@ def backrefs(portal, obj):
path = '/'.join(obj.getPhysicalPath())
uid_catalog.catalog_object(obj, path)
backrefobj.setRelatedItems(obj)
- out += str(
- 'Restore BackRelation from %s to %s \n' % (
- backrefobj,
- obj
- )
- )
- del obj._backrefs
+ logger.info(
+ 'Restored BackRelation from %s to %s' % (backrefobj, obj))
except AttributeError:
pass
- return out
-def order(obj):
- out = ''
+def restore_reforder(obj):
+ """Restore order of references stored in the attribute _relatedItemsOrder.
+ """
if not hasattr(obj, '_relatedItemsOrder'):
# Nothing to do
- return out
-
+ return
relatedItemsOrder = obj._relatedItemsOrder
uid_position_map = dict([(y, x) for x, y in enumerate(relatedItemsOrder)])
key = lambda rel: uid_position_map.get(rel.to_object.UID(), 0)
obj.relatedItems = sorted(obj.relatedItems, key=key)
- out += str('%s ordered.' % obj)
+
+
+def cleanup_stored_refs(obj):
+ """Cleanup new dx item."""
+ if safe_hasattr(obj, '_relatedItems'):
+ del obj._relatedItems
+ if safe_hasattr(obj, '_backrefs'):
+ del obj._backrefs
+ if safe_hasattr(obj, '_relatedItemsOrder'):
del obj._relatedItemsOrder
- return out
-def restoreReferences(portal):
- """ iterate over all Dexterity Objs and restore as Dexterity Reference. """
- out = ''
+def restoreReferences(portal,
+ migrate_references=True,
+ content_types=DEFAULT_TYPES):
+ """Iterate over new Dexterity items and restore Dexterity References.
+ """
catalog = getToolByName(portal, "portal_catalog")
- # Seems that these newly created objs are not reindexed
- catalog.clearFindAndRebuild()
results = catalog.searchResults(
- object_provides=IDexterityContent.__identifier__)
+ object_provides=IDexterityContent.__identifier__,
+ portal_type=content_types)
for brain in results:
obj = brain.getObject()
-
- # refs
- out += refs(obj)
- # backrefs
- out += backrefs(portal, obj)
- # order
- out += order(obj)
-
- return out
+ if migrate_references:
+ restore_refs(obj)
+ restore_backrefs(portal, obj)
+ restore_reforder(obj)
+ cleanup_stored_refs(obj)
class ReferenceMigrator(object):
diff --git a/plone/app/contenttypes/tests/test_migration.py b/plone/app/contenttypes/tests/test_migration.py
index 06fb9d6..5afa65f 100644
--- a/plone/app/contenttypes/tests/test_migration.py
+++ b/plone/app/contenttypes/tests/test_migration.py
@@ -976,6 +976,10 @@ def test_relations_are_migrated(self):
applyProfile(self.portal, 'plone.app.contenttypes:default')
migrate_documents(self.portal)
migrate_folders(self.portal)
+
+ # rebuild catalog
+ self.portal.portal_catalog.clearFindAndRebuild()
+
dx_folder1 = self.portal['folder1']
dx_folder2 = self.portal['folder2']
Repository: plone.app.contenttypes
Branch: refs/heads/1.1.x
Date: 2015-01-27T17:45:44+01:00
Author: Philip Bauer (pbauer) <bauer at starzel.de>
Commit: https://github.com/plone/plone.app.contenttypes/commit/ead846eecad210a461a946e781dd427d20452e50
logging full results when using the form
Files changed:
M plone/app/contenttypes/migration/browser.py
M plone/app/contenttypes/migration/migration.py
diff --git a/plone/app/contenttypes/migration/browser.py b/plone/app/contenttypes/migration/browser.py
index be37bd3..7c58764 100644
--- a/plone/app/contenttypes/migration/browser.py
+++ b/plone/app/contenttypes/migration/browser.py
@@ -258,6 +258,7 @@ def __call__(self,
'content_types': content_types,
'migrated_types': migrated_types,
}
+ logger.info(msg)
return stats
def stats(self):
diff --git a/plone/app/contenttypes/migration/migration.py b/plone/app/contenttypes/migration/migration.py
index 1579531..d4706c5 100644
--- a/plone/app/contenttypes/migration/migration.py
+++ b/plone/app/contenttypes/migration/migration.py
@@ -268,7 +268,7 @@ class ATCTContentMigrator(CMFItemMigrator, ReferenceMigrator):
def __init__(self, *args, **kwargs):
super(ATCTContentMigrator, self).__init__(*args, **kwargs)
logger.info(
- "Migrating object {0}".format(
+ "Migrating {0}".format(
'/'.join(self.old.getPhysicalPath())))
def beforeChange_store_comments_on_portal(self):
@@ -312,7 +312,7 @@ class ATCTFolderMigrator(CMFFolderMigrator, ReferenceMigrator):
def __init__(self, *args, **kwargs):
super(ATCTFolderMigrator, self).__init__(*args, **kwargs)
logger.info(
- "Migrating object {}".format('/'.join(self.old.getPhysicalPath())))
+ "Migrating {}".format('/'.join(self.old.getPhysicalPath())))
def beforeChange_store_comments_on_portal(self):
"""Comments from plone.app.discussion are lost when the
Repository: plone.app.contenttypes
Branch: refs/heads/1.1.x
Date: 2015-01-27T17:47:10+01:00
Author: Philip Bauer (pbauer) <bauer at starzel.de>
Commit: https://github.com/plone/plone.app.contenttypes/commit/86f4a1df56ad3dd95d709b9427f1cdf607ad8f3d
Keep migrated comments on the old objects. They will be removed with the objects.
Files changed:
M plone/app/contenttypes/migration/utils.py
diff --git a/plone/app/contenttypes/migration/utils.py b/plone/app/contenttypes/migration/utils.py
index 89813be..d283847 100644
--- a/plone/app/contenttypes/migration/utils.py
+++ b/plone/app/contenttypes/migration/utils.py
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
from Products.CMFCore.utils import getToolByName
+from Products.CMFPlone.interfaces import IPloneSiteRoot
from Products.CMFPlone.utils import safe_unicode, safe_hasattr
from Products.GenericSetup.context import DirectoryImportContext
from Products.GenericSetup.utils import importObjects
@@ -142,10 +143,14 @@ def move_comments(source_object, target_object):
logger.error('Comments exist on {0}').format(
target_object.absolute_url())
target_annotations[DISCUSSION_KEY] = deepcopy(comments)
- source_conversation = IConversation(source_object)
- for comment in source_conversation.getComments():
- del source_conversation[comment.comment_id]
- del source_annotations[DISCUSSION_KEY]
+
+ # Delete comments from the portal where wthey were stored temporarily.
+ # Comments on the old objects will be removed with the objects.
+ if IPloneSiteRoot.providedBy(source_object):
+ source_conversation = IConversation(source_object)
+ for comment in source_conversation.getComments():
+ del source_conversation[comment.comment_id]
+ del source_annotations[DISCUSSION_KEY]
def copy_contentrules(source_object, target_object):
Repository: plone.app.contenttypes
Branch: refs/heads/1.1.x
Date: 2015-01-27T17:49:40+01:00
Author: Philip Bauer (pbauer) <bauer at starzel.de>
Commit: https://github.com/plone/plone.app.contenttypes/commit/70598d137d9a25f1b8b54dd272df986cdad94238
improve test by getting the actual results when testing migrated collections
Files changed:
M plone/app/contenttypes/tests/test_migration_topic.py
diff --git a/plone/app/contenttypes/tests/test_migration_topic.py b/plone/app/contenttypes/tests/test_migration_topic.py
index d52fbdd..b24ec57 100644
--- a/plone/app/contenttypes/tests/test_migration_topic.py
+++ b/plone/app/contenttypes/tests/test_migration_topic.py
@@ -11,6 +11,7 @@
from plone.dexterity.interfaces import IDexterityFTI
from zope.component import queryUtility
from zope.interface import implementer
+from plone.app.querystring.queryparser import parseFormquery
import unittest
@@ -324,7 +325,7 @@ def test_ATCurrentAuthorCriterion(self):
)
# Check that the resulting query does not give an error.
- self.portal.topic.getQuery()
+ self.portal.topic.results
def test_ATListCriterion(self):
# The new-style queries do not currently offer the possibility
@@ -353,7 +354,7 @@ def test_ATListCriterion(self):
'v': ('Document', 'Folder')})
# Check that the resulting query does not give an error.
- self.portal.topic.getQuery()
+ self.portal.topic.results
def test_ATPathCriterion(self):
crit = self.add_criterion(
@@ -366,9 +367,14 @@ def test_ATPathCriterion(self):
[{'i': 'path',
'o': 'plone.app.querystring.operation.string.path',
'v': self.portal.folder.UID()}])
+ # check is the query is correct
+ from plone.app.querystring.queryparser import parseFormquery
+ self.assertEqual(
+ parseFormquery(self.portal, self.portal.topic.query),
+ {'path': {'query': ['/plone/folder']}})
# Check that the resulting query does not give an error.
- self.portal.topic.getQuery()
+ self.portal.topic.results
def test_ATPathCriterionNonRecursive(self):
# Topics supported non recursive search, so search at a
@@ -389,7 +395,7 @@ def test_ATPathCriterionNonRecursive(self):
'v': self.portal.folder.UID() + '::1'}])
# Check that the resulting query does not give an error.
- self.portal.topic.getQuery()
+ self.portal.topic.results
def test_ATPathCriterionMultiRecursive(self):
# Collections support multiple paths since
@@ -416,7 +422,7 @@ def test_ATPathCriterionMultiRecursive(self):
'v': self.portal.folder2.UID()})
# Check that the resulting query does not give an error.
- self.portal.topic.getQuery()
+ self.portal.topic.results
def test_ATPathCriterionMultiNonRecursive(self):
# Collections support multiple paths since
@@ -443,7 +449,7 @@ def test_ATPathCriterionMultiNonRecursive(self):
'v': self.portal.folder2.UID() + '::1'})
# Check that the resulting query does not give an error.
- self.portal.topic.getQuery()
+ self.portal.topic.results
def test_ATBooleanCriterion(self):
# Note that in standard Plone the boolean criterion is only
@@ -468,7 +474,7 @@ def test_ATBooleanCriterion(self):
)
# Check that the resulting query does not give an error.
- self.portal.topic.getQuery()
+ self.portal.topic.results
def test_ATDateRangeCriteria(self):
time1 = DateTime()
@@ -512,7 +518,7 @@ def test_ATDateRangeCriteria(self):
self.assertEqual(query[2]['v'], (time1 + 3, time1 + 5))
# Check that the resulting query does not give an error.
- self.portal.topic.getQuery()
+ self.portal.topic.results
def test_ATPortalTypeCriterion(self):
self.add_criterion(
@@ -530,7 +536,7 @@ def test_ATPortalTypeCriterion(self):
)
# Check that the resulting query does not give an error.
- self.portal.topic.getQuery()
+ self.portal.topic.results
def test_ATPortalTypeCriterionOfTopic(self):
# We migrate Topics to Collections, so we should update
@@ -548,7 +554,7 @@ def test_ATPortalTypeCriterionOfTopic(self):
'v': ('Collection',)}])
# Check that the resulting query does not give an error.
- self.portal.topic.getQuery()
+ self.portal.topic.results
def test_ATSelectionCriterion(self):
# The new-style queries do not currently offer the possibility
@@ -583,7 +589,7 @@ def test_ATSelectionCriterion(self):
'v': ('Document', 'Collection')})
# Check that the resulting query does not give an error.
- self.portal.topic.getQuery()
+ self.portal.topic.results
def test_ATSelectionCriterionForTypeTitle(self):
# 'portal_type' is the object id of the FTI in portal_types.
@@ -603,7 +609,7 @@ def test_ATSelectionCriterionForTypeTitle(self):
'v': ['Document', 'Folder']}])
# Check that the resulting query does not give an error.
- self.portal.topic.getQuery()
+ self.portal.topic.results
def test_ATReferenceCriterion(self):
# Note: the new criterion is disabled by default. Also, it
@@ -625,7 +631,7 @@ def test_ATReferenceCriterion(self):
# )
# Check that the resulting query does not give an error.
- # self.portal.topic.getQuery()
+ # self.portal.topic.results
def test_ATRelativePathCriterion(self):
crit = self.add_criterion(
@@ -643,7 +649,7 @@ def test_ATRelativePathCriterion(self):
)
# Check that the resulting query does not give an error.
- self.portal.topic.getQuery()
+ self.portal.topic.results
def test_ATRelativePathCriterionNonRecursive(self):
# Topics supported non recursive search, so search at a specific
@@ -660,7 +666,7 @@ def test_ATRelativePathCriterionNonRecursive(self):
'v': '../folder'}])
# Check that the resulting query does not give an error.
- self.portal.topic.getQuery()
+ self.portal.topic.results
def test_ATSimpleIntCriterion(self):
self.add_criterion('getObjPositionInParent', 'ATSimpleIntCriterion', 7)
@@ -672,7 +678,7 @@ def test_ATSimpleIntCriterion(self):
'v': 7}])
# Check that the resulting query does not give an error.
- self.portal.topic.getQuery()
+ self.portal.topic.results
def test_ATSimpleIntCriterionMinimum(self):
crit = self.add_criterion(
-------------------------------------------------------------------------------
-------------- next part --------------
A non-text attachment was scrubbed...
Name: CHANGES.log
Type: application/octet-stream
Size: 22950 bytes
Desc: not available
URL: <http://lists.plone.org/pipermail/plone-testbot/attachments/20150127/4843c810/attachment-0002.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: build.log
Type: application/octet-stream
Size: 189879 bytes
Desc: not available
URL: <http://lists.plone.org/pipermail/plone-testbot/attachments/20150127/4843c810/attachment-0003.obj>
More information about the Testbot
mailing list