/* * (C) Copyright 2012-2017 Nuxeo (http://nuxeo.com/) and others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Contributors: * Thierry Delprat */ package org.nuxeo.ecm.core.version.test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.util.List; import org.junit.Test; import org.nuxeo.ecm.core.CoreService; import org.nuxeo.ecm.core.api.DocumentModel; import org.nuxeo.ecm.core.api.DocumentModelList; import org.nuxeo.ecm.core.api.DocumentRef; import org.nuxeo.ecm.core.api.PathRef; import org.nuxeo.ecm.core.api.VersioningOption; import org.nuxeo.ecm.core.api.facet.VersioningDocument; import org.nuxeo.runtime.api.Framework; import org.nuxeo.runtime.test.runner.LocalDeploy; public class TestVersioningRemovalPolicy extends AbstractTestVersioning { protected DocumentModelList getVersion() { return session.query("select * from Document where ecm:isCheckedInVersion=1"); } @Test public void shouldRemoveOrphanVersionWhenLiveRemoved() { DocumentModel doc = session.createDocumentModel("/", "testfile1", "File"); doc = session.createDocument(doc); // create version doc.checkIn(VersioningOption.MINOR, null); // check out live doc doc.checkOut(); DocumentModelList vs = getVersion(); assertEquals(1, vs.size()); // now remove the doc session.removeDocument(doc.getRef()); session.save(); waitForAsyncCompletion(); // version should not be found vs = getVersion(); assertEquals(0, vs.size()); } @Test public void shouldRemoveOrphanVersionWhenLiveCheckedInRemoved() { DocumentModel doc = session.createDocumentModel("/", "testfile1", "File"); doc = session.createDocument(doc); // create version, live doc is checked in session.checkIn(doc.getRef(), VersioningOption.MINOR, null); session.save(); // version is found DocumentModelList vs = getVersion(); assertEquals(1, vs.size()); // now remove the doc session.removeDocument(doc.getRef()); session.save(); waitForAsyncCompletion(); // version should not be found vs = getVersion(); assertEquals(0, vs.size()); } @Test public void shouldRemoveOrphanVersionsWhenProxyRemovedLast() throws Exception { DocumentModel doc = session.createDocumentModel("/", "testfile1", "File"); doc = session.createDocument(doc); DocumentRef ver = doc.checkIn(VersioningOption.MINOR, ""); DocumentModel proxy = session.createProxy(ver, session.getRootDocument().getRef()); // remove the doc first session.removeDocument(doc.getRef()); session.save(); waitForAsyncCompletion(); DocumentModelList vs = getVersion(); assertEquals(1, vs.size()); // 1 version remains due to proxu // remove proxy second session.removeDocument(proxy.getRef()); session.save(); waitForAsyncCompletion(); vs = getVersion(); assertEquals(0, vs.size()); // version deleted through last proxy } // NXP-14187 @Test public void shouldRemoveOrphanVersionWhenContainingFolderRemoved() { DocumentModel ws = session.createDocumentModel("/", "ws", "Workspace"); ws = session.createDocument(ws); DocumentModel folder = session.createDocumentModel("/ws", "folder", "Folder"); folder = session.createDocument(folder); DocumentModel doc = session.createDocumentModel("/ws/folder", "file", "File"); doc = session.createDocument(doc); // create first version session.checkIn(doc.getRef(), VersioningOption.MINOR, null); session.save(); waitForAsyncCompletion(); long n = cleanupOrphanVersions(); assertEquals(0, n); // versions found DocumentModelList vs = getVersion(); assertEquals(1, vs.size()); // delete folder containing the doc session.removeDocument(folder.getRef()); session.save(); waitForAsyncCompletion(); n = cleanupOrphanVersions(); assertEquals(1, n); // versions should not be found vs = getVersion(); assertEquals(0, vs.size()); } // same test with more versions that we keep and more that we don't // NXP-14187 @Test public void shouldRemoveOrphanVersionWhenContainingFolderRemoved2() { DocumentModel ws = session.createDocumentModel("/", "ws", "Workspace"); ws = session.createDocument(ws); DocumentModel folder = session.createDocumentModel("/ws", "folder", "Folder"); folder = session.createDocument(folder); DocumentModel doc = session.createDocumentModel("/ws/folder", "file", "File"); doc = session.createDocument(doc); // create first version session.checkIn(doc.getRef(), VersioningOption.MINOR, null); // create more versions int N = 10; for (int i = 0; i < N; i++) { session.checkOut(doc.getRef()); session.checkIn(doc.getRef(), VersioningOption.MINOR, null); } // also create another live doc and two versions that should not be removed DocumentModel doc2 = session.createDocumentModel("/ws", "doc2", "File"); doc2 = session.createDocument(doc2); session.checkIn(doc2.getRef(), VersioningOption.MINOR, null); session.checkOut(doc2.getRef()); session.checkIn(doc2.getRef(), VersioningOption.MINOR, null); // also create a proxy to a version and another version in the same history, not removed either DocumentModel doc3 = session.createDocumentModel("/ws", "doc3", "File"); doc3 = session.createDocument(doc3); session.checkIn(doc3.getRef(), VersioningOption.MINOR, null); session.checkOut(doc3.getRef()); DocumentRef doc3ver2 = session.checkIn(doc3.getRef(), VersioningOption.MINOR, null); session.createProxy(doc3ver2, new PathRef("/")); session.removeDocument(doc3.getRef()); // remove live doc, keep only proxy session.save(); waitForAsyncCompletion(); long n = cleanupOrphanVersions(); assertEquals(0, n); // all versions found DocumentModelList vs = getVersion(); assertEquals((N + 1) + 2 + 2, vs.size()); // delete folder containing the doc session.removeDocument(folder.getRef()); session.save(); waitForAsyncCompletion(); n = cleanupOrphanVersions(); assertEquals(N + 1, n); // some versions (N+1) have been cleaned up vs = getVersion(); assertEquals(2 + 2, vs.size()); } protected long cleanupOrphanVersions() { CoreService coreService = Framework.getService(CoreService.class); return coreService.cleanupOrphanVersions(5); } @Test public void shouldNotRemoveOrphanVersionsWhenProxyRemovedButLiveRemains() throws Exception { DocumentModel doc = session.createDocumentModel("/", "testfile1", "File"); doc = session.createDocument(doc); DocumentRef ver = doc.checkIn(VersioningOption.MINOR, ""); DocumentModel proxy = session.createProxy(ver, session.getRootDocument().getRef()); // remove last proxy, but live doc still remains session.removeDocument(proxy.getRef()); session.save(); waitForAsyncCompletion(); DocumentModelList vs = getVersion(); assertEquals(1, vs.size()); // version not deleted } @Test @LocalDeploy("org.nuxeo.ecm.core.test.tests:test-versioning-removal-nullcontrib.xml") public void shouldNotRemoveOrphanVersions() throws Exception { DocumentModel doc = session.createDocumentModel("/", "testfile1", "File"); doc = session.createDocument(doc); VersioningDocument vdoc = doc.getAdapter(VersioningDocument.class); assertNotNull(vdoc); assertTrue(doc.isCheckedOut()); assertEquals("0.0", vdoc.getVersionLabel()); doc.checkIn(VersioningOption.MINOR, ""); assertFalse(doc.isCheckedOut()); assertEquals("0.1", vdoc.getVersionLabel()); doc.checkOut(); assertTrue(doc.isCheckedOut()); assertEquals("0.1+", vdoc.getVersionLabel()); List<DocumentModel> versions = session.getVersions(doc.getRef()); assertEquals(1, versions.size()); DocumentModelList vs = getVersion(); assertEquals(1, vs.size()); // now remove the doc session.removeDocument(doc.getRef()); session.save(); waitForAsyncCompletion(); vs = getVersion(); assertEquals(1, vs.size()); } @Test @LocalDeploy("org.nuxeo.ecm.core.test.tests:test-versioning-removal-filtercontrib.xml") public void shouldRemoveOrphanFileVersionsOnly() throws Exception { DocumentModel doc = session.createDocumentModel("/", "testfile1", "File"); doc = session.createDocument(doc); VersioningDocument vdoc = doc.getAdapter(VersioningDocument.class); assertNotNull(vdoc); assertTrue(doc.isCheckedOut()); assertEquals("0.0", vdoc.getVersionLabel()); doc.checkIn(VersioningOption.MINOR, ""); assertFalse(doc.isCheckedOut()); assertEquals("0.1", vdoc.getVersionLabel()); doc.checkOut(); assertTrue(doc.isCheckedOut()); assertEquals("0.1+", vdoc.getVersionLabel()); DocumentModel note = session.createDocumentModel("/", "testnote1", "Note"); // create document triggers automatic versioning system - note, by default, is automatically versioned note = session.createDocument(note); VersioningDocument vnote = note.getAdapter(VersioningDocument.class); assertNotNull(vnote); assertFalse(note.isCheckedOut()); assertEquals("0.1", vnote.getVersionLabel()); note.checkOut(); assertTrue(note.isCheckedOut()); assertEquals("0.1+", vnote.getVersionLabel()); List<DocumentModel> versions = session.getVersions(doc.getRef()); assertEquals(1, versions.size()); DocumentModelList vs = getVersion(); assertEquals(2, vs.size()); // now remove the doc session.removeDocument(doc.getRef()); session.removeDocument(note.getRef()); session.save(); waitForAsyncCompletion(); vs = getVersion(); assertEquals(1, vs.size()); } }