You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by re...@apache.org on 2015/07/16 16:40:36 UTC

svn commit: r1691410 - in /jackrabbit/oak/trunk: oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/ oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/ oak-commons/src/test...

Author: reschke
Date: Thu Jul 16 14:40:36 2015
New Revision: 1691410

URL: http://svn.apache.org/r1691410
Log:
fix svn:eol-style

Modified:
    jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/LargeLdapProviderTest.java   (props changed)
    jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugContextTest.java   (props changed)
    jackrabbit/oak/trunk/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/junit/LogCustomizer.java   (props changed)
    jackrabbit/oak/trunk/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/junit/LogCustomizerTest.java   (props changed)
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/StringCache.java   (props changed)
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/StringCacheTest.java   (props changed)
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/file/ExternalBlobReferenceTest.java   (props changed)
    jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/ConflictResolutionTest.java   (props changed)
    jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/ReadWithGlobRestrictionTest.java   (props changed)
    jackrabbit/oak/trunk/oak-pojosr/src/test/groovy/org/apache/jackrabbit/oak/run/osgi/SegmentNodeStoreConfigTest.groovy   (props changed)
    jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/NodeStateCopier.java   (contents, props changed)
    jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepeatedRepositoryUpgradeTest.java   (contents, props changed)
    jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/NodeStateCopierTest.java   (contents, props changed)
    jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/util/NodeStateTestUtils.java   (contents, props changed)

Propchange: jackrabbit/oak/trunk/oak-auth-ldap/src/test/java/org/apache/jackrabbit/oak/security/authentication/ldap/LargeLdapProviderTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/oak/trunk/oak-authorization-cug/src/test/java/org/apache/jackrabbit/oak/spi/security/authorization/cug/impl/CugContextTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/oak/trunk/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/junit/LogCustomizer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/oak/trunk/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/junit/LogCustomizerTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/StringCache.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/StringCacheTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/segment/file/ExternalBlobReferenceTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/ConflictResolutionTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/authorization/ReadWithGlobRestrictionTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jackrabbit/oak/trunk/oak-pojosr/src/test/groovy/org/apache/jackrabbit/oak/run/osgi/SegmentNodeStoreConfigTest.groovy
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/NodeStateCopier.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/NodeStateCopier.java?rev=1691410&r1=1691409&r2=1691410&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/NodeStateCopier.java (original)
+++ jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/NodeStateCopier.java Thu Jul 16 14:40:36 2015
@@ -1,173 +1,173 @@
-/*
- * 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.oak.upgrade.nodestate;
-
-import org.apache.jackrabbit.oak.api.CommitFailedException;
-import org.apache.jackrabbit.oak.api.PropertyState;
-import org.apache.jackrabbit.oak.commons.PathUtils;
-import org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState;
-import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
-import org.apache.jackrabbit.oak.spi.commit.EmptyHook;
-import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
-import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
-import org.apache.jackrabbit.oak.spi.state.NodeState;
-import org.apache.jackrabbit.oak.spi.state.NodeStore;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.annotation.Nonnull;
-import java.util.Collections;
-import java.util.Set;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * The NodeStateCopier and NodeStateCopier.Builder classes allow
- * recursively copying a NodeState to a NodeBuilder.
- * <br>
- * The copy algorithm is optimized for copying nodes between two
- * different NodeStore instances, i.e. where comparing NodeStates
- * is imprecise and/or expensive.
- * <br>
- * The algorithm does a post-order traversal. I.e. it copies
- * changed leaf-nodes first.
- * <br>
- * The work for a traversal without any differences between
- * {@code source} and {@code target} is equivalent to the single
- * execution of a naive equals implementation.
- */
-public class NodeStateCopier {
-
-    private static final Logger LOG = LoggerFactory.getLogger(NodeStateCopier.class);
-
-
-    private NodeStateCopier() {
-        // no instances
-    }
-
-    /**
-     * Shorthand method to copy one NodeStore to another. The changes in the
-     * target NodeStore are automatically persisted.
-     *
-     * @param source NodeStore to copy from.
-     * @param target NodeStore to copy to.
-     * @throws CommitFailedException
-     */
-    public static boolean copyNodeStore(@Nonnull final NodeStore source, @Nonnull final NodeStore target)
-            throws CommitFailedException {
-        final NodeBuilder builder = checkNotNull(target).getRoot().builder();
-        final boolean hasChanges = copyNodeState(checkNotNull(source).getRoot(), builder, "/", Collections.<String>emptySet());
-        if (hasChanges) {
-            source.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
-        }
-        return hasChanges;
-    }
-
-    /**
-     * Copies all changed properties from the source NodeState to the target
-     * NodeBuilder instance.
-     *
-     * @param source The NodeState to copy from.
-     * @param target The NodeBuilder to copy to.
-     * @return Whether changes were made or not.
-     */
-    public static boolean copyProperties(NodeState source, NodeBuilder target) {
-        boolean hasChanges = false;
-
-        // remove removed properties
-        for (final PropertyState property : target.getProperties()) {
-            final String name = property.getName();
-            if (!source.hasProperty(name)) {
-                target.removeProperty(name);
-                hasChanges = true;
-            }
-        }
-
-        // add new properties and change changed properties
-        for (PropertyState property : source.getProperties()) {
-            if (!property.equals(target.getProperty(property.getName()))) {
-                target.setProperty(property);
-                hasChanges = true;
-            }
-        }
-        return hasChanges;
-    }
-
-    /**
-     * Recursively copies the source NodeState to the target NodeBuilder.
-     * <br>
-     * Nodes that exist in the {@code target} but not in the {@code source}
-     * are removed, unless they are descendants of one of the {@code mergePaths}.
-     * This is determined by checking if the {@code currentPath} is a descendant
-     * of any of the {@code mergePaths}.
-     * <br>
-     * <b>Note:</b> changes are not persisted.
-     *
-     * @param source NodeState to copy from
-     * @param target NodeBuilder to copy to
-     * @param currentPath The path of both the source and target arguments.
-     * @param mergePaths A Set of paths under which existing nodes should be
-     *                   preserved, even if the do not exist in the source.
-     * @return An indication of whether there were changes or not.
-     */
-    public static boolean copyNodeState(@Nonnull final NodeState source, @Nonnull final NodeBuilder target,
-                                        @Nonnull final String currentPath, @Nonnull final Set<String> mergePaths) {
-
-
-        boolean hasChanges = false;
-
-        // delete deleted children
-        for (final String childName : target.getChildNodeNames()) {
-            if (!source.hasChildNode(childName) && !isMerge(PathUtils.concat(currentPath, childName), mergePaths)) {
-                target.setChildNode(childName, EmptyNodeState.MISSING_NODE);
-                hasChanges = true;
-            }
-        }
-
-        for (ChildNodeEntry child : source.getChildNodeEntries()) {
-            final String childName = child.getName();
-            final NodeState childSource = child.getNodeState();
-            if (!target.hasChildNode(childName)) {
-                // add new children
-                target.setChildNode(childName, childSource);
-                hasChanges = true;
-            } else {
-                // recurse into existing children
-                final NodeBuilder childTarget = target.getChildNode(childName);
-                final String childPath = PathUtils.concat(currentPath, childName);
-                hasChanges = copyNodeState(childSource, childTarget, childPath, mergePaths) || hasChanges;
-            }
-        }
-
-        hasChanges = copyProperties(source, target) || hasChanges;
-
-        if (hasChanges) {
-            LOG.trace("Node {} has changes", target);
-        }
-
-        return hasChanges;
-    }
-
-    private static boolean isMerge(String path, Set<String> mergePaths) {
-        for (String mergePath : mergePaths) {
-            if (PathUtils.isAncestor(mergePath, path) || mergePath.equals(path)) {
-                return true;
-            }
-        }
-        return false;
-    }
-}
+/*
+ * 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.oak.upgrade.nodestate;
+
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState;
+import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
+import org.apache.jackrabbit.oak.spi.commit.EmptyHook;
+import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeStore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.annotation.Nonnull;
+import java.util.Collections;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * The NodeStateCopier and NodeStateCopier.Builder classes allow
+ * recursively copying a NodeState to a NodeBuilder.
+ * <br>
+ * The copy algorithm is optimized for copying nodes between two
+ * different NodeStore instances, i.e. where comparing NodeStates
+ * is imprecise and/or expensive.
+ * <br>
+ * The algorithm does a post-order traversal. I.e. it copies
+ * changed leaf-nodes first.
+ * <br>
+ * The work for a traversal without any differences between
+ * {@code source} and {@code target} is equivalent to the single
+ * execution of a naive equals implementation.
+ */
+public class NodeStateCopier {
+
+    private static final Logger LOG = LoggerFactory.getLogger(NodeStateCopier.class);
+
+
+    private NodeStateCopier() {
+        // no instances
+    }
+
+    /**
+     * Shorthand method to copy one NodeStore to another. The changes in the
+     * target NodeStore are automatically persisted.
+     *
+     * @param source NodeStore to copy from.
+     * @param target NodeStore to copy to.
+     * @throws CommitFailedException
+     */
+    public static boolean copyNodeStore(@Nonnull final NodeStore source, @Nonnull final NodeStore target)
+            throws CommitFailedException {
+        final NodeBuilder builder = checkNotNull(target).getRoot().builder();
+        final boolean hasChanges = copyNodeState(checkNotNull(source).getRoot(), builder, "/", Collections.<String>emptySet());
+        if (hasChanges) {
+            source.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+        }
+        return hasChanges;
+    }
+
+    /**
+     * Copies all changed properties from the source NodeState to the target
+     * NodeBuilder instance.
+     *
+     * @param source The NodeState to copy from.
+     * @param target The NodeBuilder to copy to.
+     * @return Whether changes were made or not.
+     */
+    public static boolean copyProperties(NodeState source, NodeBuilder target) {
+        boolean hasChanges = false;
+
+        // remove removed properties
+        for (final PropertyState property : target.getProperties()) {
+            final String name = property.getName();
+            if (!source.hasProperty(name)) {
+                target.removeProperty(name);
+                hasChanges = true;
+            }
+        }
+
+        // add new properties and change changed properties
+        for (PropertyState property : source.getProperties()) {
+            if (!property.equals(target.getProperty(property.getName()))) {
+                target.setProperty(property);
+                hasChanges = true;
+            }
+        }
+        return hasChanges;
+    }
+
+    /**
+     * Recursively copies the source NodeState to the target NodeBuilder.
+     * <br>
+     * Nodes that exist in the {@code target} but not in the {@code source}
+     * are removed, unless they are descendants of one of the {@code mergePaths}.
+     * This is determined by checking if the {@code currentPath} is a descendant
+     * of any of the {@code mergePaths}.
+     * <br>
+     * <b>Note:</b> changes are not persisted.
+     *
+     * @param source NodeState to copy from
+     * @param target NodeBuilder to copy to
+     * @param currentPath The path of both the source and target arguments.
+     * @param mergePaths A Set of paths under which existing nodes should be
+     *                   preserved, even if the do not exist in the source.
+     * @return An indication of whether there were changes or not.
+     */
+    public static boolean copyNodeState(@Nonnull final NodeState source, @Nonnull final NodeBuilder target,
+                                        @Nonnull final String currentPath, @Nonnull final Set<String> mergePaths) {
+
+
+        boolean hasChanges = false;
+
+        // delete deleted children
+        for (final String childName : target.getChildNodeNames()) {
+            if (!source.hasChildNode(childName) && !isMerge(PathUtils.concat(currentPath, childName), mergePaths)) {
+                target.setChildNode(childName, EmptyNodeState.MISSING_NODE);
+                hasChanges = true;
+            }
+        }
+
+        for (ChildNodeEntry child : source.getChildNodeEntries()) {
+            final String childName = child.getName();
+            final NodeState childSource = child.getNodeState();
+            if (!target.hasChildNode(childName)) {
+                // add new children
+                target.setChildNode(childName, childSource);
+                hasChanges = true;
+            } else {
+                // recurse into existing children
+                final NodeBuilder childTarget = target.getChildNode(childName);
+                final String childPath = PathUtils.concat(currentPath, childName);
+                hasChanges = copyNodeState(childSource, childTarget, childPath, mergePaths) || hasChanges;
+            }
+        }
+
+        hasChanges = copyProperties(source, target) || hasChanges;
+
+        if (hasChanges) {
+            LOG.trace("Node {} has changes", target);
+        }
+
+        return hasChanges;
+    }
+
+    private static boolean isMerge(String path, Set<String> mergePaths) {
+        for (String mergePath : mergePaths) {
+            if (PathUtils.isAncestor(mergePath, path) || mergePath.equals(path)) {
+                return true;
+            }
+        }
+        return false;
+    }
+}

Propchange: jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/NodeStateCopier.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepeatedRepositoryUpgradeTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepeatedRepositoryUpgradeTest.java?rev=1691410&r1=1691409&r2=1691410&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepeatedRepositoryUpgradeTest.java (original)
+++ jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepeatedRepositoryUpgradeTest.java Thu Jul 16 14:40:36 2015
@@ -1,221 +1,221 @@
-/*
- * 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.oak.upgrade;
-
-import org.apache.jackrabbit.api.JackrabbitWorkspace;
-import org.apache.jackrabbit.api.security.authorization.PrivilegeManager;
-import org.apache.jackrabbit.commons.JcrUtils;
-import org.apache.jackrabbit.core.RepositoryContext;
-import org.apache.jackrabbit.core.RepositoryImpl;
-import org.apache.jackrabbit.core.config.RepositoryConfig;
-import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeStore;
-import org.apache.jackrabbit.oak.plugins.segment.file.FileStore;
-import org.apache.jackrabbit.oak.spi.lifecycle.RepositoryInitializer;
-import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
-import org.apache.jackrabbit.oak.spi.state.NodeStore;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import javax.annotation.Nonnull;
-import javax.jcr.NamespaceRegistry;
-import javax.jcr.Node;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import java.io.File;
-import java.io.IOException;
-
-/**
- * Test case to simulate an incremental upgrade, where a source repository is
- * copied to target initially. Then some modifications are made in the source
- * repository and these are (incrementally) copied to the target repository.
- * <br>
- * The expectation is that in the end the state in the target repository is
- * identical to the state in the source repository, with the exception of any
- * initial content that the upgrade tool created.
- */
-public class RepeatedRepositoryUpgradeTest extends AbstractRepositoryUpgradeTest {
-
-    private static boolean upgradeComplete;
-    private static FileStore fileStore;
-
-    @Override
-    protected NodeStore createTargetNodeStore() {
-        return new SegmentNodeStore(fileStore);
-    }
-
-    @BeforeClass
-    public static void initialize() {
-        final File dir = new File(getTestDirectory(), "segments");
-        dir.mkdirs();
-        try {
-            fileStore = FileStore.newFileStore(dir).withMaxFileSize(128).create();
-            upgradeComplete = false;
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    @AfterClass
-    public static void cleanup() {
-        fileStore.close();
-        fileStore = null;
-    }
-
-    @Before
-    public synchronized void upgradeRepository() throws Exception {
-        if (!upgradeComplete) {
-            final File sourceDir = new File(getTestDirectory(), "jackrabbit2");
-
-            sourceDir.mkdirs();
-
-            RepositoryImpl source = createSourceRepository(sourceDir);
-
-            try {
-                createSourceContent(source);
-            } finally {
-                source.shutdown();
-            }
-
-            final NodeStore target = getTargetNodeStore();
-            doUpgradeRepository(sourceDir, target);
-            fileStore.flush();
-
-            // re-create source repo
-            source = createSourceRepository(sourceDir);
-            try {
-                modifySourceContent(source);
-            } finally {
-                source.shutdown();
-            }
-
-            doUpgradeRepository(sourceDir, target);
-            fileStore.flush();
-
-            upgradeComplete = true;
-        }
-    }
-
-    @Override
-    protected void doUpgradeRepository(File source, NodeStore target) throws RepositoryException {
-        final RepositoryConfig config = RepositoryConfig.create(source);
-        final RepositoryContext context = RepositoryContext.create(config);
-        try {
-            final RepositoryUpgrade repositoryUpgrade = new RepositoryUpgrade(context, target);
-            repositoryUpgrade.copy(new RepositoryInitializer() {
-                @Override
-                public void initialize(@Nonnull NodeBuilder builder) {
-                    builder.child("foo").child("bar");
-                }
-            });
-        } finally {
-            context.getRepository().shutdown();
-        }
-    }
-
-    @Override
-    protected void createSourceContent(Repository repository) throws RepositoryException {
-        Session session = null;
-        try {
-            session = repository.login(CREDENTIALS);
-
-            registerCustomPrivileges(session);
-
-            JcrUtils.getOrCreateByPath("/content/child1/grandchild1", "nt:unstructured", session);
-            JcrUtils.getOrCreateByPath("/content/child1/grandchild2", "nt:unstructured", session);
-            JcrUtils.getOrCreateByPath("/content/child1/grandchild3", "nt:unstructured", session);
-            JcrUtils.getOrCreateByPath("/content/child2/grandchild1", "nt:unstructured", session);
-            JcrUtils.getOrCreateByPath("/content/child2/grandchild2", "nt:unstructured", session);
-
-            session.save();
-        } finally {
-            if (session != null && session.isLive()) {
-                session.logout();
-            }
-        }
-    }
-
-    private void modifySourceContent(Repository repository) throws RepositoryException {
-        Session session = null;
-        try {
-            session = repository.login(CREDENTIALS);
-
-            JcrUtils.getOrCreateByPath("/content/child2/grandchild3", "nt:unstructured", session);
-            JcrUtils.getOrCreateByPath("/content/child3", "nt:unstructured", session);
-
-            final Node child1 = JcrUtils.getOrCreateByPath("/content/child1", "nt:unstructured", session);
-            child1.remove();
-
-            session.save();
-        } finally {
-            if (session != null && session.isLive()) {
-                session.logout();
-            }
-        }
-    }
-
-    private void registerCustomPrivileges(Session session) throws RepositoryException {
-        final JackrabbitWorkspace workspace = (JackrabbitWorkspace) session.getWorkspace();
-
-        final NamespaceRegistry registry = workspace.getNamespaceRegistry();
-        registry.registerNamespace("test", "http://www.example.org/");
-
-        final PrivilegeManager privilegeManager = workspace.getPrivilegeManager();
-        privilegeManager.registerPrivilege("test:privilege", false, null);
-        privilegeManager.registerPrivilege(
-                "test:aggregate", false, new String[]{"jcr:read", "test:privilege"});
-    }
-
-    @Test
-    public void shouldReflectSourceAfterModifications() throws Exception {
-
-        assertExisting(
-                "/",
-                "/content",
-                "/content/child2",
-                "/content/child2/grandchild1",
-                "/content/child2/grandchild2",
-                "/content/child2/grandchild3",
-                "/content/child3"
-        );
-
-        assertMissing(
-                "/content/child1"
-        );
-    }
-
-    @Test
-    public void shouldContainCustomInitializerContent() throws Exception {
-        assertExisting(
-                "/foo",
-                "/foo/bar"
-        );
-    }
-
-    @Test
-    public void shouldContainUpgradeInitializedContent() throws Exception {
-        assertExisting(
-                "/rep:security",
-                "/oak:index"
-        );
-    }
-
+/*
+ * 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.oak.upgrade;
+
+import org.apache.jackrabbit.api.JackrabbitWorkspace;
+import org.apache.jackrabbit.api.security.authorization.PrivilegeManager;
+import org.apache.jackrabbit.commons.JcrUtils;
+import org.apache.jackrabbit.core.RepositoryContext;
+import org.apache.jackrabbit.core.RepositoryImpl;
+import org.apache.jackrabbit.core.config.RepositoryConfig;
+import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeStore;
+import org.apache.jackrabbit.oak.plugins.segment.file.FileStore;
+import org.apache.jackrabbit.oak.spi.lifecycle.RepositoryInitializer;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeStore;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import javax.annotation.Nonnull;
+import javax.jcr.NamespaceRegistry;
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Test case to simulate an incremental upgrade, where a source repository is
+ * copied to target initially. Then some modifications are made in the source
+ * repository and these are (incrementally) copied to the target repository.
+ * <br>
+ * The expectation is that in the end the state in the target repository is
+ * identical to the state in the source repository, with the exception of any
+ * initial content that the upgrade tool created.
+ */
+public class RepeatedRepositoryUpgradeTest extends AbstractRepositoryUpgradeTest {
+
+    private static boolean upgradeComplete;
+    private static FileStore fileStore;
+
+    @Override
+    protected NodeStore createTargetNodeStore() {
+        return new SegmentNodeStore(fileStore);
+    }
+
+    @BeforeClass
+    public static void initialize() {
+        final File dir = new File(getTestDirectory(), "segments");
+        dir.mkdirs();
+        try {
+            fileStore = FileStore.newFileStore(dir).withMaxFileSize(128).create();
+            upgradeComplete = false;
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @AfterClass
+    public static void cleanup() {
+        fileStore.close();
+        fileStore = null;
+    }
+
+    @Before
+    public synchronized void upgradeRepository() throws Exception {
+        if (!upgradeComplete) {
+            final File sourceDir = new File(getTestDirectory(), "jackrabbit2");
+
+            sourceDir.mkdirs();
+
+            RepositoryImpl source = createSourceRepository(sourceDir);
+
+            try {
+                createSourceContent(source);
+            } finally {
+                source.shutdown();
+            }
+
+            final NodeStore target = getTargetNodeStore();
+            doUpgradeRepository(sourceDir, target);
+            fileStore.flush();
+
+            // re-create source repo
+            source = createSourceRepository(sourceDir);
+            try {
+                modifySourceContent(source);
+            } finally {
+                source.shutdown();
+            }
+
+            doUpgradeRepository(sourceDir, target);
+            fileStore.flush();
+
+            upgradeComplete = true;
+        }
+    }
+
+    @Override
+    protected void doUpgradeRepository(File source, NodeStore target) throws RepositoryException {
+        final RepositoryConfig config = RepositoryConfig.create(source);
+        final RepositoryContext context = RepositoryContext.create(config);
+        try {
+            final RepositoryUpgrade repositoryUpgrade = new RepositoryUpgrade(context, target);
+            repositoryUpgrade.copy(new RepositoryInitializer() {
+                @Override
+                public void initialize(@Nonnull NodeBuilder builder) {
+                    builder.child("foo").child("bar");
+                }
+            });
+        } finally {
+            context.getRepository().shutdown();
+        }
+    }
+
+    @Override
+    protected void createSourceContent(Repository repository) throws RepositoryException {
+        Session session = null;
+        try {
+            session = repository.login(CREDENTIALS);
+
+            registerCustomPrivileges(session);
+
+            JcrUtils.getOrCreateByPath("/content/child1/grandchild1", "nt:unstructured", session);
+            JcrUtils.getOrCreateByPath("/content/child1/grandchild2", "nt:unstructured", session);
+            JcrUtils.getOrCreateByPath("/content/child1/grandchild3", "nt:unstructured", session);
+            JcrUtils.getOrCreateByPath("/content/child2/grandchild1", "nt:unstructured", session);
+            JcrUtils.getOrCreateByPath("/content/child2/grandchild2", "nt:unstructured", session);
+
+            session.save();
+        } finally {
+            if (session != null && session.isLive()) {
+                session.logout();
+            }
+        }
+    }
+
+    private void modifySourceContent(Repository repository) throws RepositoryException {
+        Session session = null;
+        try {
+            session = repository.login(CREDENTIALS);
+
+            JcrUtils.getOrCreateByPath("/content/child2/grandchild3", "nt:unstructured", session);
+            JcrUtils.getOrCreateByPath("/content/child3", "nt:unstructured", session);
+
+            final Node child1 = JcrUtils.getOrCreateByPath("/content/child1", "nt:unstructured", session);
+            child1.remove();
+
+            session.save();
+        } finally {
+            if (session != null && session.isLive()) {
+                session.logout();
+            }
+        }
+    }
+
+    private void registerCustomPrivileges(Session session) throws RepositoryException {
+        final JackrabbitWorkspace workspace = (JackrabbitWorkspace) session.getWorkspace();
+
+        final NamespaceRegistry registry = workspace.getNamespaceRegistry();
+        registry.registerNamespace("test", "http://www.example.org/");
+
+        final PrivilegeManager privilegeManager = workspace.getPrivilegeManager();
+        privilegeManager.registerPrivilege("test:privilege", false, null);
+        privilegeManager.registerPrivilege(
+                "test:aggregate", false, new String[]{"jcr:read", "test:privilege"});
+    }
+
+    @Test
+    public void shouldReflectSourceAfterModifications() throws Exception {
+
+        assertExisting(
+                "/",
+                "/content",
+                "/content/child2",
+                "/content/child2/grandchild1",
+                "/content/child2/grandchild2",
+                "/content/child2/grandchild3",
+                "/content/child3"
+        );
+
+        assertMissing(
+                "/content/child1"
+        );
+    }
+
+    @Test
+    public void shouldContainCustomInitializerContent() throws Exception {
+        assertExisting(
+                "/foo",
+                "/foo/bar"
+        );
+    }
+
+    @Test
+    public void shouldContainUpgradeInitializedContent() throws Exception {
+        assertExisting(
+                "/rep:security",
+                "/oak:index"
+        );
+    }
+
 }
\ No newline at end of file

Propchange: jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepeatedRepositoryUpgradeTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/NodeStateCopierTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/NodeStateCopierTest.java?rev=1691410&r1=1691409&r2=1691410&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/NodeStateCopierTest.java (original)
+++ jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/NodeStateCopierTest.java Thu Jul 16 14:40:36 2015
@@ -1,183 +1,183 @@
-/*
- * 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.oak.upgrade.nodestate;
-
-import com.google.common.collect.ImmutableSet;
-import org.apache.jackrabbit.oak.api.CommitFailedException;
-import org.apache.jackrabbit.oak.api.PropertyState;
-import org.apache.jackrabbit.oak.api.Type;
-import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
-import org.apache.jackrabbit.oak.spi.state.NodeState;
-import org.apache.jackrabbit.oak.spi.state.NodeStore;
-import org.junit.Test;
-
-import static com.google.common.collect.ImmutableSet.of;
-import static org.apache.jackrabbit.oak.plugins.memory.PropertyStates.createProperty;
-import static org.apache.jackrabbit.oak.upgrade.util.NodeStateTestUtils.commit;
-import static org.apache.jackrabbit.oak.upgrade.util.NodeStateTestUtils.create;
-import static org.apache.jackrabbit.oak.upgrade.util.NodeStateTestUtils.createNodeStoreWithContent;
-import static org.apache.jackrabbit.oak.upgrade.util.NodeStateTestUtils.expectDifference;
-
-public class NodeStateCopierTest {
-
-    private final PropertyState primaryType =
-            createProperty("jcr:primaryType", "nt:unstructured", Type.NAME);
-
-    @Test
-    public void shouldMergeIdenticalContent() throws CommitFailedException {
-        final NodeStore source = createPrefilledNodeStore();
-        final NodeStore target = createPrefilledNodeStore();
-
-        final NodeState before = target.getRoot();
-        NodeStateCopier.copyNodeStore(source, target);
-        final NodeState after = target.getRoot();
-
-        expectDifference().strict().verify(before, after);
-        expectDifference().strict().verify(source.getRoot(), after);
-    }
-
-    private NodeStore createPrefilledNodeStore() throws CommitFailedException {
-        final NodeStore store = createNodeStoreWithContent();
-        final NodeBuilder builder = store.getRoot().builder();
-        create(builder, "/excluded");
-        create(builder, "/a", primaryType, createProperty("name", "a"));
-        create(builder, "/a/b", primaryType, createProperty("name", "b"));
-        create(builder, "/a/b/excluded");
-        create(builder, "/a/b/c", primaryType, createProperty("name", "c"));
-        create(builder, "/a/b/c/d", primaryType);
-        create(builder, "/a/b/c/e", primaryType);
-        create(builder, "/a/b/c/f", primaryType);
-        commit(store, builder);
-        return store;
-    }
-
-    @Test
-    public void shouldRespectMergePaths() throws CommitFailedException {
-        final NodeStore source = createNodeStoreWithContent("/content/foo/en", "/content/bar/en");
-        final NodeStore target = createNodeStoreWithContent("/content/foo/de");
-
-        final NodeBuilder builder = target.getRoot().builder();
-        NodeStateCopier.copyNodeState(source.getRoot(), builder, "/", of("/content"));
-        commit(target, builder);
-        final NodeState after = target.getRoot();
-
-        expectDifference()
-                .strict()
-                .childNodeAdded("/content/foo/de")
-                .childNodeChanged("/content", "/content/foo")
-                .verify(source.getRoot(), after);
-    }
-
-
-    @Test
-    public void shouldDeleteExistingNodes() throws CommitFailedException {
-        final NodeStore source = createNodeStoreWithContent("/content/foo");
-        final NodeStore target = createNodeStoreWithContent("/content/bar");
-
-        final NodeState before = target.getRoot();
-        final NodeBuilder builder = before.builder();
-        NodeStateCopier.copyNodeState(source.getRoot(), builder, "/", ImmutableSet.<String>of());
-        commit(target, builder);
-        final NodeState after = target.getRoot();
-
-        expectDifference()
-                .strict()
-                .childNodeAdded("/content/foo")
-                .childNodeChanged("/content")
-                .childNodeDeleted("/content/bar")
-                .verify(before, after);
-    }
-
-    @Test
-    public void shouldDeleteExistingPropertyIfMissingInSource() throws CommitFailedException {
-        final NodeStore source = createNodeStoreWithContent("/a");
-        final NodeStore target = createNodeStoreWithContent();
-        NodeBuilder builder = target.getRoot().builder();
-        create(builder, "/a", primaryType);
-        commit(target, builder);
-
-        final NodeState before = target.getRoot();
-        builder = before.builder();
-        NodeStateCopier.copyNodeState(source.getRoot(), builder, "/", ImmutableSet.<String>of());
-        commit(target, builder);
-        final NodeState after = target.getRoot();
-
-        expectDifference()
-                .strict()
-                .propertyDeleted("/a/jcr:primaryType")
-                .childNodeChanged("/a")
-                .verify(before, after);
-    }
-
-    @Test
-    public void shouldNotDeleteExistingNodesIfMerged() throws CommitFailedException {
-        final NodeStore source = createNodeStoreWithContent("/content/foo");
-        final NodeStore target = createNodeStoreWithContent("/content/bar");
-
-        final NodeState before = target.getRoot();
-        final NodeBuilder builder = before.builder();
-        NodeStateCopier.copyNodeState(source.getRoot(), builder, "/", of("/content/bar"));
-        commit(target, builder);
-        final NodeState after = target.getRoot();
-
-        expectDifference()
-                .strict()
-                .childNodeAdded("/content/foo")
-                .childNodeChanged("/content")
-                .verify(before, after);
-    }
-
-    @Test
-    public void shouldNotDeleteExistingNodesIfDescendantsOfMerged() throws CommitFailedException {
-        final NodeStore source = createNodeStoreWithContent("/content/foo");
-        final NodeStore target = createNodeStoreWithContent("/content/bar");
-
-        final NodeState before = target.getRoot();
-        final NodeBuilder builder = before.builder();
-        NodeStateCopier.copyNodeState(source.getRoot(), builder, "/", of("/content"));
-        commit(target, builder);
-        final NodeState after = target.getRoot();
-
-        expectDifference()
-                .strict()
-                .childNodeAdded("/content/foo")
-                .childNodeChanged("/content")
-                .verify(before, after);
-    }
-
-    @Test
-    public void shouldIgnoreNonMatchingMergePaths() throws CommitFailedException {
-        final NodeStore source = createNodeStoreWithContent("/content/foo");
-        final NodeStore target = createNodeStoreWithContent("/content/bar");
-
-        final NodeState before = target.getRoot();
-        final NodeBuilder builder = before.builder();
-        NodeStateCopier.copyNodeState(source.getRoot(), builder, "/", of("/con"));
-        commit(target, builder);
-        final NodeState after = target.getRoot();
-
-        expectDifference()
-                .strict()
-                .childNodeAdded("/content/foo")
-                .childNodeChanged("/content")
-                .childNodeDeleted("/content/bar")
-                .verify(before, after);
-    }
-
-}
+/*
+ * 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.oak.upgrade.nodestate;
+
+import com.google.common.collect.ImmutableSet;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeStore;
+import org.junit.Test;
+
+import static com.google.common.collect.ImmutableSet.of;
+import static org.apache.jackrabbit.oak.plugins.memory.PropertyStates.createProperty;
+import static org.apache.jackrabbit.oak.upgrade.util.NodeStateTestUtils.commit;
+import static org.apache.jackrabbit.oak.upgrade.util.NodeStateTestUtils.create;
+import static org.apache.jackrabbit.oak.upgrade.util.NodeStateTestUtils.createNodeStoreWithContent;
+import static org.apache.jackrabbit.oak.upgrade.util.NodeStateTestUtils.expectDifference;
+
+public class NodeStateCopierTest {
+
+    private final PropertyState primaryType =
+            createProperty("jcr:primaryType", "nt:unstructured", Type.NAME);
+
+    @Test
+    public void shouldMergeIdenticalContent() throws CommitFailedException {
+        final NodeStore source = createPrefilledNodeStore();
+        final NodeStore target = createPrefilledNodeStore();
+
+        final NodeState before = target.getRoot();
+        NodeStateCopier.copyNodeStore(source, target);
+        final NodeState after = target.getRoot();
+
+        expectDifference().strict().verify(before, after);
+        expectDifference().strict().verify(source.getRoot(), after);
+    }
+
+    private NodeStore createPrefilledNodeStore() throws CommitFailedException {
+        final NodeStore store = createNodeStoreWithContent();
+        final NodeBuilder builder = store.getRoot().builder();
+        create(builder, "/excluded");
+        create(builder, "/a", primaryType, createProperty("name", "a"));
+        create(builder, "/a/b", primaryType, createProperty("name", "b"));
+        create(builder, "/a/b/excluded");
+        create(builder, "/a/b/c", primaryType, createProperty("name", "c"));
+        create(builder, "/a/b/c/d", primaryType);
+        create(builder, "/a/b/c/e", primaryType);
+        create(builder, "/a/b/c/f", primaryType);
+        commit(store, builder);
+        return store;
+    }
+
+    @Test
+    public void shouldRespectMergePaths() throws CommitFailedException {
+        final NodeStore source = createNodeStoreWithContent("/content/foo/en", "/content/bar/en");
+        final NodeStore target = createNodeStoreWithContent("/content/foo/de");
+
+        final NodeBuilder builder = target.getRoot().builder();
+        NodeStateCopier.copyNodeState(source.getRoot(), builder, "/", of("/content"));
+        commit(target, builder);
+        final NodeState after = target.getRoot();
+
+        expectDifference()
+                .strict()
+                .childNodeAdded("/content/foo/de")
+                .childNodeChanged("/content", "/content/foo")
+                .verify(source.getRoot(), after);
+    }
+
+
+    @Test
+    public void shouldDeleteExistingNodes() throws CommitFailedException {
+        final NodeStore source = createNodeStoreWithContent("/content/foo");
+        final NodeStore target = createNodeStoreWithContent("/content/bar");
+
+        final NodeState before = target.getRoot();
+        final NodeBuilder builder = before.builder();
+        NodeStateCopier.copyNodeState(source.getRoot(), builder, "/", ImmutableSet.<String>of());
+        commit(target, builder);
+        final NodeState after = target.getRoot();
+
+        expectDifference()
+                .strict()
+                .childNodeAdded("/content/foo")
+                .childNodeChanged("/content")
+                .childNodeDeleted("/content/bar")
+                .verify(before, after);
+    }
+
+    @Test
+    public void shouldDeleteExistingPropertyIfMissingInSource() throws CommitFailedException {
+        final NodeStore source = createNodeStoreWithContent("/a");
+        final NodeStore target = createNodeStoreWithContent();
+        NodeBuilder builder = target.getRoot().builder();
+        create(builder, "/a", primaryType);
+        commit(target, builder);
+
+        final NodeState before = target.getRoot();
+        builder = before.builder();
+        NodeStateCopier.copyNodeState(source.getRoot(), builder, "/", ImmutableSet.<String>of());
+        commit(target, builder);
+        final NodeState after = target.getRoot();
+
+        expectDifference()
+                .strict()
+                .propertyDeleted("/a/jcr:primaryType")
+                .childNodeChanged("/a")
+                .verify(before, after);
+    }
+
+    @Test
+    public void shouldNotDeleteExistingNodesIfMerged() throws CommitFailedException {
+        final NodeStore source = createNodeStoreWithContent("/content/foo");
+        final NodeStore target = createNodeStoreWithContent("/content/bar");
+
+        final NodeState before = target.getRoot();
+        final NodeBuilder builder = before.builder();
+        NodeStateCopier.copyNodeState(source.getRoot(), builder, "/", of("/content/bar"));
+        commit(target, builder);
+        final NodeState after = target.getRoot();
+
+        expectDifference()
+                .strict()
+                .childNodeAdded("/content/foo")
+                .childNodeChanged("/content")
+                .verify(before, after);
+    }
+
+    @Test
+    public void shouldNotDeleteExistingNodesIfDescendantsOfMerged() throws CommitFailedException {
+        final NodeStore source = createNodeStoreWithContent("/content/foo");
+        final NodeStore target = createNodeStoreWithContent("/content/bar");
+
+        final NodeState before = target.getRoot();
+        final NodeBuilder builder = before.builder();
+        NodeStateCopier.copyNodeState(source.getRoot(), builder, "/", of("/content"));
+        commit(target, builder);
+        final NodeState after = target.getRoot();
+
+        expectDifference()
+                .strict()
+                .childNodeAdded("/content/foo")
+                .childNodeChanged("/content")
+                .verify(before, after);
+    }
+
+    @Test
+    public void shouldIgnoreNonMatchingMergePaths() throws CommitFailedException {
+        final NodeStore source = createNodeStoreWithContent("/content/foo");
+        final NodeStore target = createNodeStoreWithContent("/content/bar");
+
+        final NodeState before = target.getRoot();
+        final NodeBuilder builder = before.builder();
+        NodeStateCopier.copyNodeState(source.getRoot(), builder, "/", of("/con"));
+        commit(target, builder);
+        final NodeState after = target.getRoot();
+
+        expectDifference()
+                .strict()
+                .childNodeAdded("/content/foo")
+                .childNodeChanged("/content")
+                .childNodeDeleted("/content/bar")
+                .verify(before, after);
+    }
+
+}

Propchange: jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/NodeStateCopierTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/util/NodeStateTestUtils.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/util/NodeStateTestUtils.java?rev=1691410&r1=1691409&r2=1691410&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/util/NodeStateTestUtils.java (original)
+++ jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/util/NodeStateTestUtils.java Thu Jul 16 14:40:36 2015
@@ -1,205 +1,205 @@
-/*
- * 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.oak.upgrade.util;
-
-import org.apache.jackrabbit.oak.api.CommitFailedException;
-import org.apache.jackrabbit.oak.api.PropertyState;
-import org.apache.jackrabbit.oak.commons.PathUtils;
-import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeStore;
-import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
-import org.apache.jackrabbit.oak.spi.commit.DefaultValidator;
-import org.apache.jackrabbit.oak.spi.commit.EditorDiff;
-import org.apache.jackrabbit.oak.spi.commit.EmptyHook;
-import org.apache.jackrabbit.oak.spi.commit.Validator;
-import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
-import org.apache.jackrabbit.oak.spi.state.NodeState;
-import org.apache.jackrabbit.oak.spi.state.NodeStore;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-
-import static org.junit.Assert.assertEquals;
-
-public class NodeStateTestUtils {
-
-    private NodeStateTestUtils() {
-        // no instances
-    }
-
-    public static NodeStore createNodeStoreWithContent(String... paths) throws CommitFailedException {
-        final SegmentNodeStore store = new SegmentNodeStore();
-        final NodeBuilder builder = store.getRoot().builder();
-        for (String path : paths) {
-            create(builder, path);
-        }
-        commit(store, builder);
-        return store;
-    }
-
-    public static void create(NodeBuilder rootBuilder, String path, PropertyState... properties) {
-        final NodeBuilder builder = createOrGetBuilder(rootBuilder, path);
-        for (PropertyState property : properties) {
-            builder.setProperty(property);
-        }
-    }
-
-    public static void commit(NodeStore store, NodeBuilder rootBuilder) throws CommitFailedException {
-        store.merge(rootBuilder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
-    }
-
-    public static NodeBuilder createOrGetBuilder(NodeBuilder builder, String path) {
-        NodeBuilder current = builder;
-        for (final String name : PathUtils.elements(path)) {
-            current = current.child(name);
-        }
-        return current;
-    }
-
-    public static ExpectedDifference expectDifference() {
-        return new ExpectedDifference();
-    }
-
-    public static class ExpectedDifference {
-
-        private ExpectedDifference() {
-        }
-
-        private final Map<String, Set<String>> expected = new HashMap<String, Set<String>>();
-
-        public void verify(NodeState before, NodeState after) {
-            final Map<String, Set<String>> actual = TestValidator.compare(before, after);
-            for (String type : expected.keySet()) {
-                if (!actual.containsKey(type)) {
-                    actual.put(type, Collections.<String>emptySet());
-                }
-                assertEquals(type, expected.get(type), actual.get(type));
-            }
-        }
-
-        public ExpectedDifference propertyAdded(String... paths) {
-            return expect("propertyAdded", paths);
-        }
-
-        public ExpectedDifference propertyChanged(String... paths) {
-            return expect("propertyChanged", paths);
-        }
-
-        public ExpectedDifference propertyDeleted(String... paths) {
-            return expect("propertyDeleted", paths);
-        }
-
-        public ExpectedDifference childNodeAdded(String... paths) {
-            return expect("childNodeAdded", paths);
-        }
-
-        public ExpectedDifference childNodeChanged(String... paths) {
-            return expect("childNodeChanged", paths);
-        }
-
-        public ExpectedDifference childNodeDeleted(String... paths) {
-            return expect("childNodeDeleted", paths);
-        }
-
-        public ExpectedDifference strict() {
-            return this.propertyAdded()
-                    .propertyChanged()
-                    .propertyDeleted()
-                    .childNodeAdded()
-                    .childNodeChanged()
-                    .childNodeDeleted();
-        }
-
-        private ExpectedDifference expect(String type, String... paths) {
-            if (!expected.containsKey(type)) {
-                expected.put(type, new TreeSet<String>());
-            }
-            Collections.addAll(expected.get(type), paths);
-            return this;
-        }
-    }
-
-    private static class TestValidator extends DefaultValidator {
-
-        final Map<String, Set<String>> actual = new HashMap<String, Set<String>>();
-
-        String path = "/";
-
-        public static Map<String, Set<String>> compare(NodeState before, NodeState after) {
-            final TestValidator validator = new TestValidator();
-            EditorDiff.process(validator, before, after);
-            return validator.actual;
-        }
-
-        @Override
-        public void leave(NodeState before, NodeState after) throws CommitFailedException {
-            path = PathUtils.getParentPath(path);
-        }
-
-        @Override
-        public void propertyAdded(PropertyState after) throws CommitFailedException {
-            record("propertyAdded", PathUtils.concat(path, after.getName()));
-        }
-
-        @Override
-        public void propertyChanged(PropertyState before, PropertyState after) throws CommitFailedException {
-            record("propertyChanged", PathUtils.concat(path, after.getName()));
-        }
-
-        @Override
-        public void propertyDeleted(PropertyState before) throws CommitFailedException {
-            record("propertyDeleted", PathUtils.concat(path, before.getName()));
-        }
-
-        @Override
-        public Validator childNodeAdded(String name, NodeState after) throws CommitFailedException {
-            path = PathUtils.concat(path, name);
-            record("childNodeAdded", path);
-            return this;
-        }
-
-        @Override
-        public Validator childNodeChanged(String name, NodeState before, NodeState after)
-                throws CommitFailedException {
-            // make sure not to record false positives (inefficient for large trees)
-            if (!before.equals(after)) {
-                path = PathUtils.concat(path, name);
-                record("childNodeChanged", path);
-                return this;
-            }
-            return null;
-        }
-
-        @Override
-        public Validator childNodeDeleted(String name, NodeState before) throws CommitFailedException {
-            path = PathUtils.concat(path, name);
-            record("childNodeDeleted", path);
-            return this;
-        }
-
-        private void record(String type, String path) {
-            if (!actual.containsKey(type)) {
-                actual.put(type, new TreeSet<String>());
-            }
-            actual.get(type).add(path);
-        }
-    }
-}
+/*
+ * 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.oak.upgrade.util;
+
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeStore;
+import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
+import org.apache.jackrabbit.oak.spi.commit.DefaultValidator;
+import org.apache.jackrabbit.oak.spi.commit.EditorDiff;
+import org.apache.jackrabbit.oak.spi.commit.EmptyHook;
+import org.apache.jackrabbit.oak.spi.commit.Validator;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeStore;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import static org.junit.Assert.assertEquals;
+
+public class NodeStateTestUtils {
+
+    private NodeStateTestUtils() {
+        // no instances
+    }
+
+    public static NodeStore createNodeStoreWithContent(String... paths) throws CommitFailedException {
+        final SegmentNodeStore store = new SegmentNodeStore();
+        final NodeBuilder builder = store.getRoot().builder();
+        for (String path : paths) {
+            create(builder, path);
+        }
+        commit(store, builder);
+        return store;
+    }
+
+    public static void create(NodeBuilder rootBuilder, String path, PropertyState... properties) {
+        final NodeBuilder builder = createOrGetBuilder(rootBuilder, path);
+        for (PropertyState property : properties) {
+            builder.setProperty(property);
+        }
+    }
+
+    public static void commit(NodeStore store, NodeBuilder rootBuilder) throws CommitFailedException {
+        store.merge(rootBuilder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+    }
+
+    public static NodeBuilder createOrGetBuilder(NodeBuilder builder, String path) {
+        NodeBuilder current = builder;
+        for (final String name : PathUtils.elements(path)) {
+            current = current.child(name);
+        }
+        return current;
+    }
+
+    public static ExpectedDifference expectDifference() {
+        return new ExpectedDifference();
+    }
+
+    public static class ExpectedDifference {
+
+        private ExpectedDifference() {
+        }
+
+        private final Map<String, Set<String>> expected = new HashMap<String, Set<String>>();
+
+        public void verify(NodeState before, NodeState after) {
+            final Map<String, Set<String>> actual = TestValidator.compare(before, after);
+            for (String type : expected.keySet()) {
+                if (!actual.containsKey(type)) {
+                    actual.put(type, Collections.<String>emptySet());
+                }
+                assertEquals(type, expected.get(type), actual.get(type));
+            }
+        }
+
+        public ExpectedDifference propertyAdded(String... paths) {
+            return expect("propertyAdded", paths);
+        }
+
+        public ExpectedDifference propertyChanged(String... paths) {
+            return expect("propertyChanged", paths);
+        }
+
+        public ExpectedDifference propertyDeleted(String... paths) {
+            return expect("propertyDeleted", paths);
+        }
+
+        public ExpectedDifference childNodeAdded(String... paths) {
+            return expect("childNodeAdded", paths);
+        }
+
+        public ExpectedDifference childNodeChanged(String... paths) {
+            return expect("childNodeChanged", paths);
+        }
+
+        public ExpectedDifference childNodeDeleted(String... paths) {
+            return expect("childNodeDeleted", paths);
+        }
+
+        public ExpectedDifference strict() {
+            return this.propertyAdded()
+                    .propertyChanged()
+                    .propertyDeleted()
+                    .childNodeAdded()
+                    .childNodeChanged()
+                    .childNodeDeleted();
+        }
+
+        private ExpectedDifference expect(String type, String... paths) {
+            if (!expected.containsKey(type)) {
+                expected.put(type, new TreeSet<String>());
+            }
+            Collections.addAll(expected.get(type), paths);
+            return this;
+        }
+    }
+
+    private static class TestValidator extends DefaultValidator {
+
+        final Map<String, Set<String>> actual = new HashMap<String, Set<String>>();
+
+        String path = "/";
+
+        public static Map<String, Set<String>> compare(NodeState before, NodeState after) {
+            final TestValidator validator = new TestValidator();
+            EditorDiff.process(validator, before, after);
+            return validator.actual;
+        }
+
+        @Override
+        public void leave(NodeState before, NodeState after) throws CommitFailedException {
+            path = PathUtils.getParentPath(path);
+        }
+
+        @Override
+        public void propertyAdded(PropertyState after) throws CommitFailedException {
+            record("propertyAdded", PathUtils.concat(path, after.getName()));
+        }
+
+        @Override
+        public void propertyChanged(PropertyState before, PropertyState after) throws CommitFailedException {
+            record("propertyChanged", PathUtils.concat(path, after.getName()));
+        }
+
+        @Override
+        public void propertyDeleted(PropertyState before) throws CommitFailedException {
+            record("propertyDeleted", PathUtils.concat(path, before.getName()));
+        }
+
+        @Override
+        public Validator childNodeAdded(String name, NodeState after) throws CommitFailedException {
+            path = PathUtils.concat(path, name);
+            record("childNodeAdded", path);
+            return this;
+        }
+
+        @Override
+        public Validator childNodeChanged(String name, NodeState before, NodeState after)
+                throws CommitFailedException {
+            // make sure not to record false positives (inefficient for large trees)
+            if (!before.equals(after)) {
+                path = PathUtils.concat(path, name);
+                record("childNodeChanged", path);
+                return this;
+            }
+            return null;
+        }
+
+        @Override
+        public Validator childNodeDeleted(String name, NodeState before) throws CommitFailedException {
+            path = PathUtils.concat(path, name);
+            record("childNodeDeleted", path);
+            return this;
+        }
+
+        private void record(String type, String path) {
+            if (!actual.containsKey(type)) {
+                actual.put(type, new TreeSet<String>());
+            }
+            actual.get(type).add(path);
+        }
+    }
+}

Propchange: jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/util/NodeStateTestUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native