def test07_getModificationDate(self):
        portal_storage = self.portal.portal_historiesstorage
        obj = Dummy()
        v1_modified = obj.modified()
        v1 = portal_storage.register(history_id=1,
                                     object=ObjectData(obj),
                                     metadata=self.buildMetadata('saved v1'))

        self.assertEqual(v1_modified,
                         portal_storage.getModificationDate(history_id=1))
        self.assertEqual(
            v1_modified,
            portal_storage.getModificationDate(history_id=1, selector=v1))

        #storage never gets the same object twice, because the archivist always generates another copy on save,
        #which then have a diffrent python id.

        #simulate object copy
        notifyModified(obj)
        obj = Dummy()
        v2_modified = obj.modified()
        v2 = portal_storage.save(history_id=1,
                                 object=ObjectData(obj),
                                 metadata=self.buildMetadata('saved v2'))
        self.assertNotEquals(v1, v2)
        self.assertEqual(v2_modified,
                         portal_storage.getModificationDate(history_id=1))
        self.assertEqual(
            v2_modified,
            portal_storage.getModificationDate(history_id=1, selector=v2))
        self.assertEqual(
            v1_modified,
            portal_storage.getModificationDate(history_id=1, selector=v1))
    def test12_retrieveNonExistentVersion(self):
        portal_storage = self.portal.portal_historiesstorage

        obj1 = Dummy()
        obj1.text = 'v1 of text'
        portal_storage.register(1,
                                ObjectData(obj1),
                                metadata=self.buildMetadata('saved v1'))

        obj2 = Dummy()
        obj2.text = 'v2 of text'
        portal_storage.save(1,
                            ObjectData(obj2),
                            metadata=self.buildMetadata('saved v2'))

        # purge
        portal_storage.purge(1, 0, metadata=self.buildMetadata("purged v1"))

        # retrieve non existing version
        self.assertRaises(StorageRetrieveError,
                          portal_storage.retrieve,
                          history_id=1,
                          selector=2,
                          countPurged=True,
                          substitute=True)

        self.assertRaises(StorageRetrieveError,
                          portal_storage.retrieve,
                          history_id=1,
                          selector=1,
                          countPurged=False)
    def _setupMinimalHistory(self):
        portal_storage = self.portal.portal_historiesstorage

        obj1 = Dummy()
        obj1.text = 'v1 of text'
        portal_storage.register(1,
                                ObjectData(obj1),
                                metadata=self.buildMetadata('saved v1'))

        obj2 = Dummy()
        obj2.text = 'v2 of text'
        portal_storage.save(1,
                            ObjectData(obj2),
                            metadata=self.buildMetadata('saved v2'))

        obj3 = Dummy()
        obj3.text = 'v3 of text'
        portal_storage.save(1,
                            ObjectData(obj3),
                            metadata=self.buildMetadata('saved v3'))

        obj4 = Dummy()
        obj4.text = 'v4 of text'
        portal_storage.save(1,
                            ObjectData(obj4),
                            metadata=self.buildMetadata('saved v4'))
 def test13_saveWithUnicodeComment(self):
     portal_storage = self.portal.portal_historiesstorage
     obj1 = Dummy()
     obj1.text = 'v1 of text'
     portal_storage.register(1, ObjectData(obj1),
                             metadata=self.buildMetadata('saved v1'))
     portal_storage.save(1, ObjectData(obj1),
                         metadata=self.buildMetadata(u'saved v1\xc3\xa1'))
    def test01_saveAfterRegisteringDoesNotRaiseException(self):
        portal_storage = self.portal.portal_historiesstorage
        obj = Dummy()

        sel = portal_storage.register(1, ObjectData(obj),
                                      metadata=self.buildMetadata('saved'))
        self.assertEqual(sel, 0)
        sel = portal_storage.save(1, ObjectData(obj),
                                  metadata=self.buildMetadata('saved'))
        self.assertEqual(sel, 1)
    def test02_saveUnregisteredObjectRaisesException(self):
        portal_storage = self.portal.portal_historiesstorage
        obj = Dummy()

        self.assertRaises(StorageUnregisteredError,
                          portal_storage.save,
                          1, ObjectData(obj), metadata=self.buildMetadata('saved'))
 def test16_delete_history_on_content_deletion(self):
     """ If a content item gets deleted, delete it's history
     as well
     """
     portal_hidhandler = self.portal.portal_historyidhandler
     portal_storage = self.portal.portal_historiesstorage
     self.portal.invokeFactory('Document', 'doc')
     self.portal.invokeFactory('Link', 'link')
     self.portal.invokeFactory('Folder', 'folder')
     # the event subscriber should be able to handle unversioned content
     self.portal.invokeFactory('Document', 'unversioned_doc')
     doc = self.portal.doc
     doc_histid = portal_hidhandler.register(doc)
     portal_storage.register(
         doc_histid, ObjectData(aq_base(doc)),
         metadata=self.buildMetadata('initial'))
     portal_storage.save(
         doc_histid,
         ObjectData(aq_base(doc)),
         metadata=self.buildMetadata('v2'))
     link = self.portal.link
     link_histid = portal_hidhandler.register(link)
     portal_storage.register(
         link_histid, ObjectData(aq_base(link)),
         metadata=self.buildMetadata('initial'))
     folder = self.portal.folder
     folder_histid = portal_hidhandler.register(folder)
     portal_storage.register(
         folder_histid, ObjectData(aq_base(folder)),
         metadata=self.buildMetadata('first draft'))
     dochist = portal_storage.retrieve(doc_histid).object
     doctype = dochist.object.portal_type
     self.assertEqual('Document', doctype)
     linkhist = portal_storage.retrieve(link_histid).object
     linktype = linkhist.object.portal_type
     self.assertEqual('Link', linktype)
     folderhist = portal_storage.retrieve(folder_histid).object
     foldertype = folderhist.object.portal_type
     self.assertEqual('Folder', foldertype)
     self.portal.manage_delObjects(
         ids=['doc', 'link', 'folder', 'unversioned_doc'])
     removed_doc = portal_storage.retrieve(history_id=doc_histid)
     self.assertTrue(type(removed_doc.object) == Removed)
     removed_link = portal_storage.retrieve(history_id=link_histid)
     self.assertTrue(type(removed_link.object) == Removed)
     removed_folder = portal_storage.retrieve(history_id=folder_histid)
     self.assertTrue(type(removed_folder.object) == Removed)
    def test05_getHistory(self):
        portal_storage = self.portal.portal_historiesstorage

        obj1 = Dummy()
        obj1.text = 'v1 of text'
        portal_storage.register(1,
                                ObjectData(obj1),
                                metadata=self.buildMetadata('saved v1'))

        obj2 = Dummy()
        obj2.text = 'v2 of text'
        portal_storage.save(1,
                            ObjectData(obj2),
                            metadata=self.buildMetadata('saved v2'))

        obj3 = Dummy()
        obj3.text = 'v3 of text'
        portal_storage.save(1,
                            ObjectData(obj3),
                            metadata=self.buildMetadata('saved v3'))

        history = portal_storage.getHistory(history_id=1)
        length = len(history)

        # check length
        self.assertEquals(length, 3)

        # iterating over the history
        for i, vdata in enumerate(history):
            expected_test = 'v%s of text' % (i + 1)
            self.assertEquals(vdata.object.object.text, expected_test)
            self.assertEquals(history[i].object.object.text, expected_test)

            expected_comment = 'saved v%s' % (i + 1)
            self.assertEqual(self.getComment(vdata), expected_comment)
            self.assertEqual(self.getComment(history[i]), expected_comment)

        # accessing the versions
        self.assertEquals(history[0].object.object.text, "v1 of text")
        self.assertEqual(self.getComment(history[0]), "saved v1")
        self.assertEquals(history[1].object.object.text, "v2 of text")
        self.assertEqual(self.getComment(history[1]), "saved v2")
        self.assertEquals(history[2].object.object.text, "v3 of text")
        self.assertEqual(self.getComment(history[2]), "saved v3")
    def test03_saveAndRetrieve(self):
        portal_storage = self.portal.portal_historiesstorage

        obj1 = Dummy()
        obj1.text = 'v1 of text'
        portal_storage.register(1, ObjectData(obj1), metadata=self.buildMetadata('saved v1'))

        obj2 = Dummy()
        obj2.text = 'v2 of text'
        portal_storage.save(1, ObjectData(obj2), metadata=self.buildMetadata('saved v2'))

        # retrieve the state at registration time
        retrieved_obj = portal_storage.retrieve(history_id=1, selector=0)
        self.assertEqual(retrieved_obj.object.object.text, 'v1 of text')
        self.assertEqual(self.getComment(retrieved_obj), 'saved v1')

        # just check if first save wasn't a double save
        retrieved_obj = portal_storage.retrieve(history_id=1, selector=1)
        self.assertEqual(retrieved_obj.object.object.text, 'v2 of text')
        self.assertEqual(self.getComment(retrieved_obj), 'saved v2')
    def test06_checkObjectManagerIntegrity(self):
        portal_storage = self.portal.portal_historiesstorage

        om = DummyOM()
        sub1 = Dummy()
        sub2 = Dummy()
        om._setObject('sub1', sub1)
        om._setObject('sub2', sub2)
        self.assertEqual(len(om.objectIds()), 2)
        portal_storage.register(1, ObjectData(om), metadata=self.buildMetadata('saved v1'))
        vdata = portal_storage.retrieve(history_id=1, selector=0)
        retrieved_om = vdata.object
        self.assertEqual(len(retrieved_om.object.objectIds()), 2)
    def test15_storageStatistics(self):
        self.maxDiff = None
        portal_storage = self.portal.portal_historiesstorage

        cmf_uid = 1
        obj1 = CMFDummy('obj', cmf_uid)
        obj1.text = 'v1 of text'
        portal_storage.register(cmf_uid,
                                ObjectData(obj1),
                                metadata=self.buildMetadata('saved v1'))

        obj2 = CMFDummy('obj', cmf_uid)
        obj2.text = 'v2 of text'
        portal_storage.save(cmf_uid,
                            ObjectData(obj2),
                            metadata=self.buildMetadata('saved v2'))

        obj3 = CMFDummy('obj', cmf_uid)
        obj3.text = 'v3 of text'
        portal_storage.save(cmf_uid,
                            ObjectData(obj3),
                            metadata=self.buildMetadata('saved v3'))

        obj4 = CMFDummy('obj', cmf_uid)
        obj4.text = 'v4 of text'
        self.portal._setObject('obj', obj4)
        self.portal.portal_catalog.indexObject(self.portal.obj)
        portal_storage.save(cmf_uid,
                            ObjectData(obj4),
                            metadata=self.buildMetadata('saved v4'))

        cmf_uid = 2
        tomorrow = DateTime() + 1
        obj5 = CMFDummy('tomorrow', cmf_uid, effective=tomorrow)
        obj5.allowedRolesAndUsers = ['Anonymous']
        self.portal._setObject('tomorrow', obj5)
        self.portal.portal_catalog.indexObject(self.portal.tomorrow)
        portal_storage.register(
            cmf_uid,
            ObjectData(obj5),
            metadata=self.buildMetadata('effective tomorrow'))

        cmf_uid = 3
        yesterday = DateTime() - 1
        obj6 = CMFDummy('yesterday', cmf_uid, expires=yesterday)
        obj6.allowedRolesAndUsers = ['Anonymous']
        self.portal._setObject('yesterday', obj6)
        self.portal.portal_catalog.indexObject(self.portal.yesterday)
        portal_storage.register(
            cmf_uid,
            ObjectData(obj6),
            metadata=self.buildMetadata('expired yesterday'))

        cmf_uid = 4
        obj7 = CMFDummy('public', cmf_uid)
        obj7.text = 'visible for everyone'
        obj7.allowedRolesAndUsers = ['Anonymous']
        self.portal._setObject('public', obj7)
        self.portal.portal_catalog.indexObject(self.portal.public)
        portal_storage.register(cmf_uid,
                                ObjectData(obj7),
                                metadata=self.buildMetadata('saved public'))

        got = portal_storage.zmi_getStorageStatistics()
        expected = {
            'deleted': [],
            'summaries': {
                'totalHistories': 4,
                'deletedVersions': 0,
                'existingVersions': 7,
                'deletedHistories': 0,
                # time may easily be different
                # 'time': '0.00',
                'totalVersions': 7,
                'existingAverage': '1.8',
                'existingHistories': 4,
                'deletedAverage': 'n/a',
                'totalAverage': '1.8'
            },
            'existing': [{
                'url': 'http://nohost/plone/obj',
                'history_id': 1,
                'length': 4,
                'path': '/obj',
                'sizeState': 'approximate',
                'portal_type': 'Dummy',
            }, {
                'url': 'http://nohost/plone/tomorrow',
                'history_id': 2,
                'length': 1,
                'path': '/tomorrow',
                'sizeState': 'approximate',
                'portal_type': 'Dummy',
            }, {
                'url': 'http://nohost/plone/yesterday',
                'history_id': 3,
                'length': 1,
                'path': '/yesterday',
                'sizeState': 'approximate',
                'portal_type': 'Dummy',
            }, {
                'url': 'http://nohost/plone/public',
                'history_id': 4,
                'length': 1,
                'path': '/public',
                'sizeState': 'approximate',
                'portal_type': 'Dummy',
            }]
        }
        self.assertEqual(expected['deleted'], got['deleted'])
        self.assertTrue('summaries' in got)
        self.assertTrue('time' in got['summaries'])
        for key, value in expected['summaries'].items():
            self.assertEqual(value, got['summaries'][key])
        self.assertEqual(len(expected['existing']), len(got['existing']))
        for idx in range(len(expected['existing'])):
            exp = expected['existing'][idx]
            actual = got['existing'][idx]
            for key, value in exp.items():
                self.assertEqual(actual[key], value)
            # The actual size is not important and we want robust tests,
            # s. https://github.com/plone/Products.CMFEditions/issues/31
            self.failUnless(actual['size'] > 0)
    def test11_purgeOnSave(self):
        # install the purge policy that removes all except the current and
        # previous objects
        self.installPurgePolicyTool()
        portal_storage = self.portal.portal_historiesstorage

        # save no 1
        obj1 = Dummy()
        obj1.text = 'v1 of text'

        sel = portal_storage.register(1,
                                      ObjectData(obj1),
                                      metadata=self.buildMetadata('saved v1'))
        history = portal_storage.getHistory(1, countPurged=False)

        self.assertEquals(sel, 0)
        self.assertEquals(len(history), 1)
        self.assertEqual(history[0].object.object.text, 'v1 of text')
        self.assertEqual(self.getComment(history[0]), 'saved v1')

        # save no 2
        obj2 = Dummy()
        obj2.text = 'v2 of text'
        sel = portal_storage.save(1,
                                  ObjectData(obj2),
                                  metadata=self.buildMetadata('saved v2'))
        history = portal_storage.getHistory(1, countPurged=False)

        self.assertEquals(sel, 1)
        self.assertEquals(len(history), 2)
        self.assertEqual(history[0].object.object.text, 'v1 of text')
        self.assertEqual(self.getComment(history[0]), 'saved v1')
        self.assertEqual(history[1].object.object.text, 'v2 of text')
        self.assertEqual(self.getComment(history[1]), 'saved v2')

        # save no 3: purged oldest version
        obj3 = Dummy()
        obj3.text = 'v3 of text'
        sel = portal_storage.save(1,
                                  ObjectData(obj3),
                                  metadata=self.buildMetadata('saved v3'))
        history = portal_storage.getHistory(1, countPurged=False)
        length = len(history)

        # iterating over the history
        for i, vdata in enumerate(history):
            self.assertEquals(vdata.object.object.text,
                              'v%s of text' % (i + 2))
            self.assertEqual(self.getComment(vdata), 'saved v%s' % (i + 2))

        self.assertEquals(sel, 2)
        self.assertEquals(length, 2)
        self.assertEqual(history[0].object.object.text, 'v2 of text')
        self.assertEqual(self.getComment(history[0]), 'saved v2')
        self.assertEqual(history[1].object.object.text, 'v3 of text')
        self.assertEqual(self.getComment(history[1]), 'saved v3')

        # save no 4: purged oldest version
        obj4 = Dummy()
        obj4.text = 'v4 of text'
        sel = portal_storage.save(1,
                                  ObjectData(obj4),
                                  metadata=self.buildMetadata('saved v4'))
        history = portal_storage.getHistory(1, countPurged=False)
        length = len(history)

        # iterating over the history
        for i, vdata in enumerate(history):
            self.assertEquals(vdata.object.object.text,
                              'v%s of text' % (i + 3))
            self.assertEqual(self.getComment(vdata), 'saved v%s' % (i + 3))

        self.assertEquals(sel, 3)
        self.assertEquals(length, 2)
        self.assertEqual(history[0].object.object.text, 'v3 of text')
        self.assertEqual(self.getComment(history[0]), 'saved v3')
        self.assertEqual(history[1].object.object.text, 'v4 of text')
        self.assertEqual(self.getComment(history[1]), 'saved v4')
Exemple #13
0
    def prepare(self, obj, app_metadata=None, sys_metadata={}):
        obj, history_id = dereference(obj)
        if history_id is None:
            # object isn't under version control yet
            # An working copy beeing under version control needs to have
            # a history_id, version_id (starts with 0) and a location_id
            # (the current implementation isn't able yet to handle multiple
            # locations. Nevertheless lets set the location id to a well
            # known default value)
            portal_hidhandler = getToolByName(obj, 'portal_historyidhandler')
            history_id = portal_hidhandler.register(obj)
            version_id = obj.version_id = 0
            obj.location_id = 0
            is_registered = False
        else:
            version_id = len(self.queryHistory(obj))
            is_registered = True

        base_obj = aq_base(obj)
        doc1_inside = getattr(base_obj, 'doc1_inside', None)
        doc2_inside = getattr(base_obj, 'doc2_inside', None)
        doc3_outside = getattr(base_obj, 'doc3_outside', None)

        # simulate clone modifiers
        icrefs = []
        ocrefs = []
        clone = deepCopy(base_obj)
        if doc1_inside is not None:
            icrefs.append(ObjectManagerStorageAdapter(clone, 'doc1_inside'))
        if doc2_inside is not None:
            icrefs.append(ObjectManagerStorageAdapter(clone, 'doc2_inside'))
        if doc3_outside is not None:
            ocrefs.append(ObjectManagerStorageAdapter(clone, 'doc3_outside'))
        crefs = icrefs + ocrefs

        # simulate before save modifier
        iorefs = []
        oorefs = []
        if doc1_inside is not None:
            iorefs.append(getattr(obj, 'doc1_inside'))
        if doc2_inside is not None:
            iorefs.append(getattr(obj, 'doc2_inside'))
        if doc3_outside is not None:
            oorefs.append(getattr(obj, 'doc3_outside'))
        orefs = iorefs + oorefs
        for cref in crefs:
            cref.setAttribute(VersionAwareReference())

        # log
        if sys_metadata['originator'] is None:
            self.log("")
        if orefs:
            self.log("%sprepare %s: hid=%s, refs=(%s)"
                        % (self.alog_indent,
                           obj.getId(),
                           history_id,
                           ', '.join([ref.getId() for ref in orefs])))
        else:
            self.log("%sprepare %s: hid=%s"
                        % (self.alog_indent, obj.getId(), history_id))
        self.alog_indent += '  '

        # prepare object structure
        original_info = ObjectData(obj, iorefs, oorefs)
        clone_info = ObjectData(clone, icrefs, ocrefs)

        approxSize = None

        return PreparedObject(history_id, original_info, clone_info, (),
                              app_metadata, sys_metadata, is_registered, approxSize)
Exemple #14
0
    def test15_storageStatistics(self):
        self.maxDiff = None
        portal_storage = self.portal.portal_historiesstorage

        cmf_uid = 1
        obj1 = CMFDummy('obj', cmf_uid)
        obj1.text = 'v1 of text'
        portal_storage.register(cmf_uid,
                                ObjectData(obj1),
                                metadata=self.buildMetadata('saved v1'))

        obj2 = CMFDummy('obj', cmf_uid)
        obj2.text = 'v2 of text'
        portal_storage.save(cmf_uid,
                            ObjectData(obj2),
                            metadata=self.buildMetadata('saved v2'))

        obj3 = CMFDummy('obj', cmf_uid)
        obj3.text = 'v3 of text'
        portal_storage.save(cmf_uid,
                            ObjectData(obj3),
                            metadata=self.buildMetadata('saved v3'))

        obj4 = CMFDummy('obj', cmf_uid)
        obj4.text = 'v4 of text'
        self.portal._setObject('obj', obj4)
        self.portal.portal_catalog.indexObject(self.portal.obj)
        portal_storage.save(cmf_uid,
                            ObjectData(obj4),
                            metadata=self.buildMetadata('saved v4'))

        cmf_uid = 2
        tomorrow = DateTime() + 1
        obj5 = CMFDummy('tomorrow', cmf_uid, effective=tomorrow)
        obj5.allowedRolesAndUsers = ['Anonymous']
        self.portal._setObject('tomorrow', obj5)
        self.portal.portal_catalog.indexObject(self.portal.tomorrow)
        portal_storage.register(
            cmf_uid,
            ObjectData(obj5),
            metadata=self.buildMetadata('effective tomorrow'))

        cmf_uid = 3
        yesterday = DateTime() - 1
        obj6 = CMFDummy('yesterday', cmf_uid, expires=yesterday)
        obj6.allowedRolesAndUsers = ['Anonymous']
        self.portal._setObject('yesterday', obj6)
        self.portal.portal_catalog.indexObject(self.portal.yesterday)
        portal_storage.register(
            cmf_uid,
            ObjectData(obj6),
            metadata=self.buildMetadata('expired yesterday'))

        cmf_uid = 4
        obj7 = CMFDummy('public', cmf_uid)
        obj7.text = 'visible for everyone'
        obj7.allowedRolesAndUsers = ['Anonymous']
        self.portal._setObject('public', obj7)
        self.portal.portal_catalog.indexObject(self.portal.public)
        portal_storage.register(cmf_uid,
                                ObjectData(obj7),
                                metadata=self.buildMetadata('saved public'))

        got = portal_storage.zmi_getStorageStatistics()
        expected = {
            'deleted': [],
            'summaries': {
                'totalHistories': 4,
                'deletedVersions': 0,
                'existingVersions': 7,
                'deletedHistories': 0,
                'time': '0.00',
                'totalVersions': 7,
                'existingAverage': '1.8',
                'existingHistories': 4,
                'deletedAverage': 'n/a',
                'totalAverage': '1.8'
            },
            'existing': [{
                'url': 'http://nohost/plone/obj',
                'history_id': 1,
                'length': 4,
                'path': '/obj',
                'sizeState': 'approximate',
                'portal_type': 'Dummy',
                'size': 1718
            }, {
                'url': 'http://nohost/plone/tomorrow',
                'history_id': 2,
                'length': 1,
                'path': '/tomorrow',
                'sizeState': 'approximate',
                'portal_type': 'Dummy',
                'size': 555
            }, {
                'url': 'http://nohost/plone/yesterday',
                'history_id': 3,
                'length': 1,
                'path': '/yesterday',
                'sizeState': 'approximate',
                'portal_type': 'Dummy',
                'size': 557
            }, {
                'url': 'http://nohost/plone/public',
                'history_id': 4,
                'length': 1,
                'path': '/public',
                'sizeState': 'approximate',
                'portal_type': 'Dummy',
                'size': 557
            }]
        }
        self.assertEqual(expected, got)