jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mreut...@apache.org
Subject svn commit: r789279 - in /jackrabbit/trunk/jackrabbit-core/src: main/java/org/apache/jackrabbit/core/state/ test/java/org/apache/jackrabbit/core/
Date Mon, 29 Jun 2009 10:29:32 GMT
Author: mreutegg
Date: Mon Jun 29 10:29:32 2009
New Revision: 789279

URL: http://svn.apache.org/viewvc?rev=789279&view=rev
Log:
JCR-2129: Prevent data inconsistencies due to incorrect or missed merges in the ItemStateManagers

Added:
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentAddRemoveMoveTest.java
  (with props)
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentAddRemovePropertyTest.java
  (with props)
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentMixinModificationTest.java
  (with props)
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentModificationBase.java
  (with props)
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentModificationWithSNSTest.java
  (with props)
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentMoveTest.java
  (with props)
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentReorderTest.java
  (with props)
Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ChangeLog.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/NodeStateMerger.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentNodeModificationTest.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/TestAll.java

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ChangeLog.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ChangeLog.java?rev=789279&r1=789278&r2=789279&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ChangeLog.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/ChangeLog.java
Mon Jun 29 10:29:32 2009
@@ -160,6 +160,18 @@
     }
 
     /**
+     * Returns a flag indicating whether a given item state is marked as
+     * modified in this log.
+     *
+     * @param id the id of the item.
+     * @return <code>true</code> if the item state is marked as modified in this
+     *         log; <code>false</code> otherwise.
+     */
+    public boolean isModified(ItemId id) {
+        return modifiedStates.containsKey(id);
+    }
+
+    /**
      * Return a node references object given its id. Returns
      * <code>null</code> if the node reference is not in the modified
      * section.

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java?rev=789279&r1=789278&r2=789279&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java
Mon Jun 29 10:29:32 2009
@@ -425,9 +425,7 @@
                 cache.cache(local);
             }
         }
-        if (local != null) {
-            dispatcher.notifyStateCreated(created);
-        }
+        dispatcher.notifyStateCreated(created);
     }
 
     /**

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/NodeStateMerger.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/NodeStateMerger.java?rev=789279&r1=789278&r2=789279&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/NodeStateMerger.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/NodeStateMerger.java
Mon Jun 29 10:29:32 2009
@@ -102,7 +102,7 @@
 
                     for (ChildNodeEntry cne : state.getAddedChildNodeEntries()) {
 
-                        if (context.isAdded(cne.getId())) {
+                        if (context.isAdded(cne.getId()) || context.isModified(cne.getId()))
{
                             // a new child node entry has been added to this state;
                             // check for name collisions with other state
                             if (overlayedState.hasChildNodeEntry(cne.getName())) {
@@ -117,13 +117,17 @@
                             }
 
                             added.add(cne);
+                        } else {
+                            // externally added
                         }
                     }
 
                     for (ChildNodeEntry cne : state.getRemovedChildNodeEntries()) {
-                        if (context.isDeleted(cne.getId())) {
+                        if (context.isDeleted(cne.getId()) || context.isModified(cne.getId()))
{
                             // a child node entry has been removed from this node state
                             removed.add(cne);
+                        } else {
+                            // externally removed
                         }
                     }
 
@@ -148,14 +152,6 @@
                         PropertyId propId =
                                 new PropertyId(state.getNodeId(), name);
                         if (context.isAdded(propId)) {
-                            // a new property name has been added to this state;
-                            // check for name collisions
-                            if (overlayedState.hasPropertyName(name)
-                                    || overlayedState.hasChildNodeEntry(name)) {
-                                // conflicting names
-                                return false;
-                            }
-
                             added.add(name);
                         }
                     }
@@ -195,6 +191,7 @@
     static interface MergeContext {
         boolean isAdded(ItemId id);
         boolean isDeleted(ItemId id);
+        boolean isModified(ItemId id);
         boolean allowsSameNameSiblings(NodeId id);
     }
 }

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java?rev=789279&r1=789278&r2=789279&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java
Mon Jun 29 10:29:32 2009
@@ -787,9 +787,23 @@
             // local state was created
             ItemState transientState = transientStore.get(created.getId());
             if (transientState != null) {
-                // underlying state has been permanently created
-                transientState.pull();
-                transientState.setStatus(ItemState.STATUS_EXISTING);
+                if (transientState.hasOverlayedState()) {
+                    // underlying state has been permanently created
+                    transientState.pull();
+                    transientState.setStatus(ItemState.STATUS_EXISTING);
+                } else {
+                    // this is a notification from another session
+                    try {
+                        ItemState local = stateMgr.getItemState(created.getId());
+                        transientState.connect(local);
+                        // update mod count
+                        transientState.setModCount(local.getModCount());
+                        transientState.setStatus(ItemState.STATUS_EXISTING_MODIFIED);
+                    } catch (ItemStateException e) {
+                        // something went wrong, mark as stale
+                        transientState.setStatus(ItemState.STATUS_STALE_MODIFIED);
+                    }
+                }
                 visibleState = transientState;
             }
         }
@@ -823,6 +837,12 @@
                                     return atticStore.contains(id);
                                 }
 
+                                public boolean isModified(ItemId id) {
+                                    ItemState is = transientStore.get(id);
+                                    return is != null
+                                            && is.getStatus() == ItemState.STATUS_EXISTING_MODIFIED;
+                                }
+
                                 public boolean allowsSameNameSiblings(NodeId id) {
                                     NodeState ns;
                                     try {
@@ -867,6 +887,13 @@
             if (transientState != null) {
                 transientState.setStatus(ItemState.STATUS_STALE_DESTROYED);
                 visibleState = transientState;
+            } else {
+                // check attic
+                transientState = atticStore.get(destroyed.getId());
+                if (transientState != null) {
+                    atticStore.remove(destroyed.getId());
+                    transientState.onDisposed();
+                }
             }
         }
         dispatcher.notifyStateDestroyed(visibleState);

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java?rev=789279&r1=789278&r2=789279&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java
Mon Jun 29 10:29:32 2009
@@ -618,6 +618,10 @@
                                             return local.deleted(id);
                                         }
 
+                                        public boolean isModified(ItemId id) {
+                                            return local.isModified(id);
+                                        }
+
                                         public boolean allowsSameNameSiblings(NodeId id)
{
                                             NodeState ns;
                                             try {

Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentAddRemoveMoveTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentAddRemoveMoveTest.java?rev=789279&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentAddRemoveMoveTest.java
(added)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentAddRemoveMoveTest.java
Mon Jun 29 10:29:32 2009
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.jackrabbit.core;
+
+import javax.jcr.InvalidItemStateException;
+import javax.jcr.Node;
+
+public final class ConcurrentAddRemoveMoveTest extends ConcurrentModificationBase {
+
+    /**
+     * {@inheritDoc}
+     */
+    public void setUp() throws Exception {
+        super.setUp();
+        testRootNode.addNode("A").addNode("B");
+        testRootNode.addNode("C");
+        testRootNode.getSession().save();
+    }
+
+    public void testAddWithMoveFrom() throws Exception {
+        testRootNode.getNode("A").addNode("D");
+        session.move(testRoot + "/A/B", testRoot + "/C/B");
+
+        superuser.save();
+
+        try {
+            session.save();
+        } catch (InvalidItemStateException e) {
+            fail("must not throw exception");
+        }
+    }
+
+    public void testAddWithMoveTo() throws Exception {
+        testRootNode.getNode("A").addNode("D");
+        session.move(testRoot + "/C", testRoot + "/A/C");
+
+        superuser.save();
+
+        try {
+            session.save();
+        } catch (InvalidItemStateException e) {
+            fail("must not throw exception");
+        }
+    }
+
+    public void testRemoveWithMoveFrom() throws Exception {
+        Node d = testRootNode.getNode("A").addNode("D");
+        superuser.save();
+        d.remove();
+        session.move(testRoot + "/A/B", testRoot + "/C/B");
+
+        superuser.save();
+
+        try {
+            session.save();
+        } catch (InvalidItemStateException e) {
+            fail("must not throw exception");
+        }
+    }
+
+    public void testRemoveWithMoveTo() throws Exception {
+        Node d = testRootNode.getNode("A").addNode("D");
+        superuser.save();
+        d.remove();
+        session.move(testRoot + "/C", testRoot + "/A/C");
+
+        superuser.save();
+
+        try {
+            session.save();
+        } catch (InvalidItemStateException e) {
+            fail("must not throw exception");
+        }
+    }
+
+    public void testMoveFromWithAdd() throws Exception {
+        superuser.move(testRoot + "/A/B", testRoot + "/C/B");
+        session.getNode(testRoot).getNode("A").addNode("D");
+
+        superuser.save();
+
+        try {
+            session.save();
+        } catch (InvalidItemStateException e) {
+            fail("must not throw exception");
+        }
+    }
+
+    public void testMoveToWithAdd() throws Exception {
+        superuser.move(testRoot + "/C", testRoot + "/A/C");
+        session.getNode(testRoot).getNode("A").addNode("D");
+
+        superuser.save();
+
+        try {
+            session.save();
+        } catch (InvalidItemStateException e) {
+            fail("must not throw exception");
+        }
+    }
+
+    public void testMoveFromWithRemove() throws Exception {
+        Node d = session.getNode(testRoot).getNode("A").addNode("D");
+        session.save();
+
+        superuser.move(testRoot + "/A/B", testRoot + "/C/B");
+        d.remove();
+
+        superuser.save();
+
+        try {
+            session.save();
+        } catch (InvalidItemStateException e) {
+            fail("must not throw exception");
+        }
+    }
+
+    public void testMoveToWithRemove() throws Exception {
+        Node d = session.getNode(testRoot).getNode("A").addNode("D");
+        session.save();
+
+        superuser.move(testRoot + "/C", testRoot + "/A/C");
+        d.remove();
+
+        testRootNode.getSession().save();
+
+        try {
+            session.save();
+        } catch (InvalidItemStateException e) {
+            fail("must not throw exception");
+        }
+    }
+
+    //-------------------------< concurrent add >-------------------------------
+
+    public void testAddAdd() throws Exception {
+        testRootNode.getNode("A").addNode("D");
+        session.getNode(testRoot).getNode("A").addNode("E");
+
+        superuser.save();
+
+        try {
+            session.save();
+        } catch (InvalidItemStateException e) {
+            fail("must not throw exception");
+        }
+    }
+
+    //-------------------------< concurrent remove >----------------------------
+
+    public void testRemoveRemove() throws Exception {
+        Node d = testRootNode.getNode("A").addNode("D");
+        superuser.save();
+        d.remove();
+        session.getNode(testRoot).getNode("A").getNode("B").remove();
+
+        superuser.save();
+
+        try {
+            session.save();
+        } catch (InvalidItemStateException e) {
+            fail("must not throw exception");
+        }
+    }
+}

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentAddRemoveMoveTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentAddRemovePropertyTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentAddRemovePropertyTest.java?rev=789279&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentAddRemovePropertyTest.java
(added)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentAddRemovePropertyTest.java
Mon Jun 29 10:29:32 2009
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.jackrabbit.core;
+
+import javax.jcr.Node;
+import javax.jcr.InvalidItemStateException;
+
+/**
+ * <code>ConcurrentAddRemovePropertyTest</code> checks if concurrently adding
+ * and removing properties does not throw an InvalidItemStateException.
+ */
+public class ConcurrentAddRemovePropertyTest extends ConcurrentModificationBase {
+
+    public void testAdd() throws Exception {
+        Node n = testRootNode.addNode(nodeName1);
+        superuser.save();
+        n.setProperty(propertyName1, "foo");
+        session.getNode(testRoot).getNode(nodeName1).setProperty(propertyName2, "bar");
+        superuser.save();
+        try {
+            session.save();
+        } catch (InvalidItemStateException e) {
+            fail("must not throw InvalidItemStateException");
+        }
+    }
+
+    public void testAddSameName() throws Exception {
+        Node n = testRootNode.addNode(nodeName1);
+        superuser.save();
+        n.setProperty(propertyName1, "foo");
+        session.getNode(testRoot).getNode(nodeName1).setProperty(propertyName1, "bar");
+        superuser.save();
+        try {
+            session.save();
+        } catch (InvalidItemStateException e) {
+            fail("must not throw InvalidItemStateException");
+        }
+        assertEquals("bar", n.getProperty(propertyName1).getString());
+    }
+
+    public void testRemove() throws Exception {
+        Node n = testRootNode.addNode(nodeName1);
+        n.setProperty(propertyName1, "foo");
+        n.setProperty(propertyName2, "bar");
+        superuser.save();
+        n.getProperty(propertyName1).remove();
+        session.getNode(testRoot).getNode(nodeName1).getProperty(propertyName2).remove();
+        superuser.save();
+        try {
+            session.save();
+        } catch (InvalidItemStateException e) {
+            fail("must not throw InvalidItemStateException");
+        }
+    }
+
+    public void testRemoveSameName() throws Exception {
+        Node n = testRootNode.addNode(nodeName1);
+        n.setProperty(propertyName1, "foo");
+        superuser.save();
+        n.getProperty(propertyName1).remove();
+        session.getNode(testRoot).getNode(nodeName1).getProperty(propertyName1).remove();
+        superuser.save();
+        try {
+            session.save();
+        } catch (InvalidItemStateException e) {
+            fail("must not throw InvalidItemStateException");
+        }
+    }
+}

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentAddRemovePropertyTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentMixinModificationTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentMixinModificationTest.java?rev=789279&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentMixinModificationTest.java
(added)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentMixinModificationTest.java
Mon Jun 29 10:29:32 2009
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.jackrabbit.core;
+
+import javax.jcr.Node;
+import javax.jcr.InvalidItemStateException;
+
+/**
+ * <code>ConcurrentMixinModificationTest</code> checks if concurrent
+ * modifications of mixins trigger an InvalidItemStateException.
+ */
+public class ConcurrentMixinModificationTest extends ConcurrentModificationBase {
+
+    public void testMixin() throws Exception {
+        Node n = testRootNode.addNode(nodeName1);
+        superuser.save();
+        n.addMixin(mixReferenceable);
+        session.getNode(testRoot).getNode(nodeName1).addMixin(mixLockable);
+        superuser.save();
+        try {
+            session.save();
+            fail("InvalidItemStateException expected");
+        } catch (InvalidItemStateException e) {
+            // expected
+        }
+    }
+}

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentMixinModificationTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentModificationBase.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentModificationBase.java?rev=789279&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentModificationBase.java
(added)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentModificationBase.java
Mon Jun 29 10:29:32 2009
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.jackrabbit.core;
+
+import javax.jcr.Session;
+
+import org.apache.jackrabbit.test.AbstractJCRTest;
+
+/**
+ * <code>ConcurrentModificationBase</code> is a base class for concurrent
+ * modification tests.
+ */
+public abstract class ConcurrentModificationBase extends AbstractJCRTest {
+
+    protected Session session;
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        session = helper.getSuperuserSession();
+    }
+
+    protected void tearDown() throws Exception {
+        if (session != null) {
+            session.logout();
+            session = null;
+        }
+        super.tearDown();
+    }
+}

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentModificationBase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentModificationWithSNSTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentModificationWithSNSTest.java?rev=789279&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentModificationWithSNSTest.java
(added)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentModificationWithSNSTest.java
Mon Jun 29 10:29:32 2009
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.jackrabbit.core;
+
+import javax.jcr.InvalidItemStateException;
+import javax.jcr.Node;
+
+/**
+ * <code>ConcurrentModificationWithSNSTest</code> checks if interleaving node
+ * modifications with same name siblings do not throw InvalidItemStateException.
+ */
+public class ConcurrentModificationWithSNSTest extends ConcurrentModificationBase {
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        testRootNode.addNode("A");
+        testRootNode.addNode("A");
+        testRootNode.addNode("A");
+        superuser.save();
+    }
+
+    public void testAddAdd() throws Exception {
+        testRootNode.addNode("A");
+        session.getNode(testRoot).addNode("A");
+        superuser.save();
+        try {
+            session.save();
+        } catch (InvalidItemStateException e) {
+            fail("must not throw InvalidItemStateException");
+        }
+    }
+
+    public void testAddRemove() throws Exception {
+        testRootNode.addNode("A");
+        session.getNode(testRoot).getNode("A[2]").remove();
+        superuser.save();
+        try {
+            session.save();
+        } catch (InvalidItemStateException e) {
+            fail("must not throw InvalidItemStateException");
+        }
+    }
+
+    public void testRemoveAdd() throws Exception {
+        testRootNode.getNode("A[2]").remove();
+        session.getNode(testRoot).addNode("A");
+        superuser.save();
+        try {
+            session.save();
+        } catch (InvalidItemStateException e) {
+            fail("must not throw InvalidItemStateException");
+        }
+    }
+
+    public void testRemoveRemove() throws Exception {
+        testRootNode.getNode("A[1]").remove();
+        session.getNode(testRoot).getNode("A[3]").remove();
+        superuser.save();
+        try {
+            session.save();
+        } catch (InvalidItemStateException e) {
+            fail("must not throw InvalidItemStateException");
+        }
+    }
+
+    public void testSNSNotAllowed() throws Exception {
+        cleanUpTestRoot(superuser);
+        Node f = testRootNode.addNode("folder", "nt:folder");
+        superuser.save();
+        f.addNode("A", "nt:folder");
+        session.getNode(f.getPath()).addNode("A", "nt:folder");
+        superuser.save();
+        try {
+            session.save();
+            fail("InvalidItemStateException expected");
+        } catch (InvalidItemStateException e) {
+            // expected
+        }
+    }
+}

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentModificationWithSNSTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentMoveTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentMoveTest.java?rev=789279&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentMoveTest.java
(added)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentMoveTest.java
Mon Jun 29 10:29:32 2009
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.jackrabbit.core;
+
+import javax.jcr.InvalidItemStateException;
+
+/**
+ * <code>ConcurrentMoveTest</code>...
+ */
+public class ConcurrentMoveTest extends ConcurrentModificationBase {
+
+    protected String srcAbsPath;
+
+    protected String destAbsPath1;
+
+    protected String destAbsPath2;
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        srcAbsPath = testRootNode.addNode("A").getPath();
+        destAbsPath1 = testRootNode.addNode("B").getPath() + "/D";
+        destAbsPath2 = testRootNode.addNode("C").getPath() + "/D";
+        superuser.save();
+    }
+
+    public void testMove() throws Exception {
+        superuser.move(srcAbsPath, destAbsPath1);
+        session.move(srcAbsPath, destAbsPath2);
+        superuser.save();
+        try {
+            session.save();
+            fail("InvalidItemStateException expected");
+        } catch (InvalidItemStateException e) {
+            // expected
+        }
+    }
+}

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentMoveTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentNodeModificationTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentNodeModificationTest.java?rev=789279&r1=789278&r2=789279&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentNodeModificationTest.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentNodeModificationTest.java
Mon Jun 29 10:29:32 2009
@@ -120,7 +120,17 @@
                     state = "adding property to subnode " + i;
                     n1.setProperty("testprop", "xxx");
                     if (i % 10 == 0) {
-                        state = "saving pending subnodes";
+                        state = "saving pending (added) subnodes";
+                        session.save();
+                    }
+                    randomSleep();
+                }
+
+                for (int i = 0; i < NUM_NODES; i++) {
+                    state = "removing subnode " + i;
+                    n.getNode("x" + identity + i).remove();
+                    if (i % 10 == 0) {
+                        state = "saving pending (removed) subnodes";
                         session.save();
                     }
                     randomSleep();

Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentReorderTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentReorderTest.java?rev=789279&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentReorderTest.java
(added)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentReorderTest.java
Mon Jun 29 10:29:32 2009
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.jackrabbit.core;
+
+import javax.jcr.InvalidItemStateException;
+
+/**
+ * <code>ConcurrentReorderTest</code> checks if a reorder interleaved with
+ * a modification by another session throws an InvalidItemStateException.
+ */
+public class ConcurrentReorderTest extends ConcurrentModificationBase {
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        testRootNode.addNode("A");
+        testRootNode.addNode("B");
+        testRootNode.addNode("C");
+        superuser.save();
+    }
+
+    public void testReorderWithAdd() throws Exception {
+        testRootNode.orderBefore("C", "A");
+        session.getNode(testRoot).addNode("D");
+        session.save();
+        try {
+            superuser.save();
+            fail("must throw InvalidItemStateException");
+        } catch (InvalidItemStateException e) {
+            // expected
+        }
+    }
+
+    public void testAddWithReorder() throws Exception {
+        testRootNode.addNode("D");
+        session.getNode(testRoot).orderBefore("C", "A");
+        session.save();
+        try {
+            superuser.save();
+            fail("must throw InvalidItemStateException");
+        } catch (InvalidItemStateException e) {
+            // expected
+        }
+    }
+}

Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/ConcurrentReorderTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/TestAll.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/TestAll.java?rev=789279&r1=789278&r2=789279&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/TestAll.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/TestAll.java
Mon Jun 29 10:29:32 2009
@@ -43,6 +43,14 @@
         suite.addTestSuite(SessionGarbageCollectedTest.class);
         suite.addTestSuite(ReferencesTest.class);
 
+        // test related to NodeStateMerger
+        suite.addTestSuite(ConcurrentAddRemoveMoveTest.class);
+        suite.addTestSuite(ConcurrentAddRemovePropertyTest.class);
+        suite.addTestSuite(ConcurrentMixinModificationTest.class);
+        suite.addTestSuite(ConcurrentModificationWithSNSTest.class);
+        suite.addTestSuite(ConcurrentMoveTest.class);
+        suite.addTestSuite(ConcurrentReorderTest.class);
+
         return suite;
     }
 }



Mime
View raw message