Author: tomekr Date: Thu Dec 1 12:06:57 2016 New Revision: 1772181 URL: http://svn.apache.org/viewvc?rev=1772181&view=rev Log: OAK-5193: Version tree may become inconsistent after removing a version
Modified: jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/ReadWriteVersionManager.java jackrabbit/oak/branches/1.2/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/version/VersionableTest.java Modified: jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/ReadWriteVersionManager.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/ReadWriteVersionManager.java?rev=1772181&r1=1772180&r2=1772181&view=diff ============================================================================== --- jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/ReadWriteVersionManager.java (original) +++ jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/ReadWriteVersionManager.java Thu Dec 1 12:06:57 2016 @@ -194,7 +194,7 @@ class ReadWriteVersionManager extends Re pb.setName(JCR_PREDECESSORS).setValues(successor.getProperty(JCR_PREDECESSORS).getValue(Type.REFERENCES)); pb.removeValue(versionId); - pb.setValues(predecessorIds.getValue(Type.REFERENCES)); + pb.addValues(predecessorIds.getValue(Type.REFERENCES)); successor.setProperty(pb.getPropertyState()); } @@ -205,7 +205,7 @@ class ReadWriteVersionManager extends Re pb.setName(JCR_SUCCESSORS).setValues(predecessor.getProperty(JCR_SUCCESSORS).getValue(Type.REFERENCES)); pb.removeValue(versionId); - pb.setValues(successorIds.getValue(Type.REFERENCES)); + pb.addValues(successorIds.getValue(Type.REFERENCES)); predecessor.setProperty(pb.getPropertyState()); } Modified: jackrabbit/oak/branches/1.2/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/version/VersionableTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/version/VersionableTest.java?rev=1772181&r1=1772180&r2=1772181&view=diff ============================================================================== --- jackrabbit/oak/branches/1.2/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/version/VersionableTest.java (original) +++ jackrabbit/oak/branches/1.2/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/version/VersionableTest.java Thu Dec 1 12:06:57 2016 @@ -16,6 +16,7 @@ */ package org.apache.jackrabbit.oak.jcr.version; +import javax.annotation.Nullable; import javax.jcr.Node; import javax.jcr.NodeIterator; import javax.jcr.Property; @@ -23,11 +24,20 @@ import javax.jcr.PropertyType; import javax.jcr.RepositoryException; import javax.jcr.version.Version; import javax.jcr.version.VersionException; +import javax.jcr.version.VersionHistory; import javax.jcr.version.VersionManager; +import com.google.common.base.Function; import org.apache.jackrabbit.JcrConstants; import org.apache.jackrabbit.test.AbstractJCRTest; +import java.util.Set; + +import static com.google.common.collect.ImmutableSet.of; +import static com.google.common.collect.Lists.transform; +import static com.google.common.collect.Sets.newHashSet; +import static java.util.Arrays.asList; + /** * {@code VersionableTest} contains tests for method relevant to * versionable nodes. @@ -283,4 +293,45 @@ public class VersionableTest extends Abs superuser.save(); } -} + // OAK-5193 + public void testSuccessorsPredecessorsMergedOnRemove() throws Exception { + Node node = testRootNode.addNode(nodeName1, ntUnstructured); + node.addMixin(mixVersionable); + superuser.save(); + + VersionManager vm = superuser.getWorkspace().getVersionManager(); + VersionHistory history = vm.getVersionHistory(node.getPath()); + + vm.checkpoint(node.getPath()); // 1.0 + Version v11 = vm.checkpoint(node.getPath()); + vm.checkpoint(node.getPath()); // 1.2 + vm.checkpoint(node.getPath()); // 1.3 + vm.restore(v11, true); + vm.checkpoint(node.getPath()); // 1.1 + vm.checkpoint(node.getPath()); // 1.1.0 + assertSuccessors(history, of("1.1.0", "1.2"), "1.1"); + vm.checkpoint(node.getPath()); // 1.1.1 + + history.removeVersion("1.2"); + assertSuccessors(history, of("1.1.0", "1.3"), "1.1"); + } + + private static void assertSuccessors(VersionHistory history, Set<String> expectedSuccessors, String versionName) throws RepositoryException { + assertEquals(expectedSuccessors, getNames(history.getVersion(versionName).getSuccessors())); + } + + private static Set<String> getNames(Version[] versions) { + return newHashSet(transform(asList(versions), new Function<Version, String>() { + @Nullable + @Override + public String apply(@Nullable Version input) { + try { + return input.getName(); + } catch (RepositoryException e) { + return null; + } + } + })); + } + +} \ No newline at end of file