Author: tomekr
Date: Thu Dec  1 11:59:31 2016
New Revision: 1772179

URL: http://svn.apache.org/viewvc?rev=1772179&view=rev
Log:
OAK-5193: Version tree may become inconsistent after removing a version

Modified:
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/ReadWriteVersionManager.java
    
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/version/VersionableTest.java

Modified: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/ReadWriteVersionManager.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/ReadWriteVersionManager.java?rev=1772179&r1=1772178&r2=1772179&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/ReadWriteVersionManager.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/ReadWriteVersionManager.java
 Thu Dec  1 11:59:31 2016
@@ -199,7 +199,7 @@ public class ReadWriteVersionManager ext
             
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());
         }
@@ -210,7 +210,7 @@ public class ReadWriteVersionManager ext
             
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/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/version/VersionableTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/version/VersionableTest.java?rev=1772179&r1=1772178&r2=1772179&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/version/VersionableTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/version/VersionableTest.java
 Thu Dec  1 11:59:31 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


Reply via email to