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 to...@apache.org on 2016/12/16 11:12:54 UTC

svn commit: r1774571 [3/3] - in /jackrabbit/oak/branches/1.4/oak-upgrade/src: main/java/org/apache/jackrabbit/core/ main/java/org/apache/jackrabbit/oak/upgrade/ main/java/org/apache/jackrabbit/oak/upgrade/blob/ main/java/org/apache/jackrabbit/oak/upgra...

Modified: jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/LongNameTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/LongNameTest.java?rev=1774571&r1=1774570&r2=1774571&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/LongNameTest.java (original)
+++ jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/LongNameTest.java Fri Dec 16 11:12:53 2016
@@ -20,6 +20,7 @@ package org.apache.jackrabbit.oak.upgrad
 
 import static com.google.common.collect.Iterables.cycle;
 import static com.google.common.collect.Iterables.limit;
+import static org.junit.Assert.fail;
 
 import java.io.File;
 import java.io.IOException;
@@ -34,17 +35,16 @@ import org.apache.commons.io.FileUtils;
 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.document.DocumentMK;
 import org.apache.jackrabbit.oak.plugins.document.DocumentNodeStore;
+import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeStore;
 import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeStore;
-import org.apache.jackrabbit.oak.plugins.segment.SegmentStore;
 import org.apache.jackrabbit.oak.plugins.segment.memory.MemoryStore;
-import org.apache.jackrabbit.oak.plugins.document.DocumentMK;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.apache.jackrabbit.oak.spi.state.NodeStore;
 import org.apache.jackrabbit.oak.stats.Clock;
 import org.junit.Assert;
 import org.junit.BeforeClass;
-import org.junit.Ignore;
 import org.junit.Test;
 
 public class LongNameTest {
@@ -65,7 +65,8 @@ public class LongNameTest {
         FileUtils.deleteQuietly(crx2RepoDir);
 
         sourceRepositoryConfig = createCrx2Config(crx2RepoDir);
-        RepositoryImpl sourceRepository = RepositoryImpl.create(sourceRepositoryConfig);
+        RepositoryContext ctx = RepositoryContext.create(sourceRepositoryConfig);
+        RepositoryImpl sourceRepository = ctx.getRepository();
         Session session = sourceRepository.login(CREDENTIALS);
         try {
             Assert.assertTrue(TOO_LONG_NAME.getBytes().length > 150);
@@ -80,6 +81,7 @@ public class LongNameTest {
 
             Assert.assertTrue(longNameParent.hasNode(TOO_LONG_NAME));
             Assert.assertTrue(longNameParent.hasNode(NOT_TOO_LONG_NAME));
+
         } finally {
             session.logout();
         }
@@ -96,7 +98,7 @@ public class LongNameTest {
     public void longNameShouldBeSkipped() throws RepositoryException, IOException {
         DocumentNodeStore nodeStore = new DocumentMK.Builder().getNodeStore();
         try {
-            upgrade(nodeStore, true);
+            upgrade(nodeStore, false, true);
 
             NodeState parent = getParent(nodeStore.getRoot());
             Assert.assertTrue(parent.hasChildNode(NOT_TOO_LONG_NAME));
@@ -109,39 +111,50 @@ public class LongNameTest {
         }
     }
 
+    @Test
+    public void assertNoLongNamesTest() throws IOException, RepositoryException {
+        RepositoryConfig config = createCrx2Config(crx2RepoDir);
+        RepositoryContext context = RepositoryContext.create(config);
+        try {
+            RepositoryUpgrade upgrade = new RepositoryUpgrade(context, new MemoryNodeStore());
+            try {
+                upgrade.assertNoLongNames();
+                fail("Exception should be thrown");
+            } catch (RepositoryException e) {
+                // that's fine
+            }
+        } finally {
+            context.getRepository().shutdown();
+        }
+    }
+
     @Test(expected = RepositoryException.class)
-    @Ignore
     public void longNameOnDocumentStoreThrowsAnException() throws RepositoryException, IOException {
         DocumentNodeStore nodeStore = new DocumentMK.Builder().getNodeStore();
         try {
-            upgrade(nodeStore, false);
+            upgrade(nodeStore, false, false);
         } finally {
             nodeStore.dispose();
         }
     }
 
     @Test
-    @Ignore
     public void longNameOnSegmentStoreWorksFine() throws RepositoryException, IOException {
-        SegmentStore memoryStore = new MemoryStore();
-        try {
-            SegmentNodeStore nodeStore = SegmentNodeStore.newSegmentNodeStore(memoryStore).create();
-            upgrade(nodeStore, false);
+        NodeStore nodeStore = SegmentNodeStore.newSegmentNodeStore(new MemoryStore()).create();
+        upgrade(nodeStore, false, false);
 
-            NodeState parent = getParent(nodeStore.getRoot());
-            Assert.assertTrue(parent.hasChildNode(NOT_TOO_LONG_NAME));
-            Assert.assertTrue(parent.hasChildNode(TOO_LONG_NAME));
-        } finally {
-            memoryStore.close();
-        }
+        NodeState parent = getParent(nodeStore.getRoot());
+        Assert.assertTrue(parent.hasChildNode(NOT_TOO_LONG_NAME));
+        Assert.assertTrue(parent.hasChildNode(TOO_LONG_NAME));
     }
 
-    private static void upgrade(NodeStore target, boolean skipLongNames) throws RepositoryException, IOException {
+    private static void upgrade(NodeStore target, boolean skipNameCheck, boolean filterLongNames) throws RepositoryException, IOException {
         RepositoryConfig config = createCrx2Config(crx2RepoDir);
         RepositoryContext context = RepositoryContext.create(config);
         try {
             RepositoryUpgrade upgrade = new RepositoryUpgrade(context, target);
-            upgrade.setSkipLongNames(skipLongNames);
+            upgrade.setCheckLongNames(skipNameCheck);
+            upgrade.setFilterLongNames(filterLongNames);
             upgrade.copy(null);
         } finally {
             context.getRepository().shutdown();

Modified: jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepeatedRepositorySidegradeTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepeatedRepositorySidegradeTest.java?rev=1774571&r1=1774570&r2=1774571&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepeatedRepositorySidegradeTest.java (original)
+++ jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepeatedRepositorySidegradeTest.java Fri Dec 16 11:12:53 2016
@@ -86,7 +86,6 @@ public class RepeatedRepositorySidegrade
         SegmentNodeStore segmentNodeStore = SegmentNodeStore.newSegmentNodeStore(fileStore).create();
         try {
             final RepositorySidegrade repositoryUpgrade = new RepositorySidegrade(segmentNodeStore, target);
-            repositoryUpgrade.setSkipInitialization(skipInit);
             repositoryUpgrade.copy(new RepositoryInitializer() {
                 @Override
                 public void initialize(@Nonnull NodeBuilder builder) {

Modified: jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegradeTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegradeTest.java?rev=1774571&r1=1774570&r2=1774571&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegradeTest.java (original)
+++ jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegradeTest.java Fri Dec 16 11:12:53 2016
@@ -98,26 +98,10 @@ public class RepositorySidegradeTest {
     public JackrabbitSession createAdminSession() throws RepositoryException {
         return (JackrabbitSession) targetRepository.login(CREDENTIALS);
     }
-    
-    // OAK-2869
-    private static void setAsync(NodeStore source) throws Exception {
-        NodeBuilder builder = source.getRoot().builder();
-        builder.child(":async").setProperty("test", "123");
-        source.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
-    }
-    
-    // OAK-2869
-    @Test
-    public void verifyAsync() throws Exception {
-        NodeState state = targetNodeStore.getRoot().getChildNode(":async");
-        assertFalse(state.hasProperty("test"));
-    }
 
     @SuppressWarnings("unchecked")
     protected NodeStore createSourceContent() throws Exception {
         NodeStore source = new SegmentNodeStore();
-        setAsync(source);
-        
         Repository repository = new Jcr(new Oak(source)).createRepository();
 
         Session session = repository.login(CREDENTIALS);

Modified: jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/SameNodeSiblingsTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/SameNodeSiblingsTest.java?rev=1774571&r1=1774570&r2=1774571&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/SameNodeSiblingsTest.java (original)
+++ jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/SameNodeSiblingsTest.java Fri Dec 16 11:12:53 2016
@@ -24,6 +24,8 @@ import static org.junit.Assert.assertEqu
 
 import java.io.File;
 import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.util.Set;
 
 import javax.jcr.Credentials;
@@ -43,8 +45,6 @@ import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
-import com.google.common.io.Files;
-
 public class SameNodeSiblingsTest {
 
     public static final Credentials CREDENTIALS = new SimpleCredentials("admin", "admin".toCharArray());
@@ -53,7 +53,7 @@ public class SameNodeSiblingsTest {
 
     @Before
     public void createCrx2RepoDir() throws IOException {
-        crx2RepoDir = Files.createTempDir();
+        crx2RepoDir = Files.createTempDirectory(Paths.get("target"), "repo-crx2").toFile();
     }
 
     @After

Added: jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/UpgradeOldSegmentTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/UpgradeOldSegmentTest.java?rev=1774571&view=auto
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/UpgradeOldSegmentTest.java (added)
+++ jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/UpgradeOldSegmentTest.java Fri Dec 16 11:12:53 2016
@@ -0,0 +1,118 @@
+/*
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.InputStream;
+import java.io.StringReader;
+
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.nodetype.NodeTypeManager;
+import javax.jcr.nodetype.PropertyDefinition;
+
+import com.google.common.collect.Iterators;
+import org.apache.commons.io.FileUtils;
+import org.apache.jackrabbit.api.JackrabbitRepository;
+import org.apache.jackrabbit.commons.cnd.CndImporter;
+import org.apache.jackrabbit.oak.jcr.Jcr;
+import org.apache.jackrabbit.oak.upgrade.cli.OakUpgrade;
+import org.apache.jackrabbit.oak.upgrade.cli.Util;
+import org.apache.jackrabbit.oak.upgrade.cli.container.SegmentNodeStoreContainer;
+import org.junit.Test;
+
+public class UpgradeOldSegmentTest {
+
+    @Test
+    public void upgradeFrom10() throws Exception {
+        File testFolder = new File(new File("target"), UpgradeOldSegmentTest.class.getSimpleName());
+        FileUtils.deleteDirectory(testFolder);
+        File oldRepo = new File(testFolder, "test-repo-1.0");
+        oldRepo.mkdirs();
+        try (InputStream in = UpgradeOldSegmentTest.class.getResourceAsStream("/test-repo-1.0.zip")) {
+            Util.unzip(in, oldRepo);
+        }
+
+        SegmentNodeStoreContainer newRepoContainer = new SegmentNodeStoreContainer();
+        OakUpgrade.main(oldRepo.getPath(), newRepoContainer.getDescription());
+
+        Repository repo = new Jcr(newRepoContainer.open()).createRepository();
+        Session s = repo.login(new SimpleCredentials("admin", "admin".toCharArray()));
+
+        Node myType = s.getNode("/jcr:system/jcr:nodeTypes/test:MyType");
+        assertEquals(2, Iterators.size(myType.getNodes("jcr:propertyDefinition")));
+
+        NodeTypeManager ntMgr = s.getWorkspace().getNodeTypeManager();
+        assertTrue(ntMgr.hasNodeType("test:MyType"));
+        NodeType nt = ntMgr.getNodeType("test:MyType");
+        PropertyDefinition[] pDefs = nt.getDeclaredPropertyDefinitions();
+        assertEquals(2, pDefs.length);
+        for (PropertyDefinition pd : pDefs) {
+            String name = pd.getName();
+            if (name.equals("test:mandatory")) {
+                assertTrue(pd.isMandatory());
+            } else if (name.equals("test:optional")) {
+                assertFalse(pd.isMandatory());
+            } else {
+                fail("Unexpected property definition: " + name);
+            }
+        }
+
+        // flip mandatory flag for test:mandatory
+        String cnd = "<'test'='http://www.apache.org/jackrabbit/test'>\n" +
+                "[test:MyType] > nt:unstructured\n" +
+                " - test:mandatory (string)\n" +
+                " - test:optional (string)";
+
+        CndImporter.registerNodeTypes(new StringReader(cnd), s, true);
+
+        myType = s.getNode("/jcr:system/jcr:nodeTypes/test:MyType");
+        assertEquals(2, Iterators.size(myType.getNodes("jcr:propertyDefinition")));
+
+        nt = ntMgr.getNodeType("test:MyType");
+        pDefs = nt.getDeclaredPropertyDefinitions();
+        assertEquals(2, pDefs.length);
+        for (PropertyDefinition pd : pDefs) {
+            String name = pd.getName();
+            if (name.equals("test:mandatory")) {
+                assertFalse(pd.isMandatory());
+            } else if (name.equals("test:optional")) {
+                assertFalse(pd.isMandatory());
+            } else {
+                fail("Unexpected property definition: " + name);
+            }
+        }
+
+        s.logout();
+        if (repo instanceof JackrabbitRepository) {
+            ((JackrabbitRepository) repo).shutdown();
+        }
+        newRepoContainer.close();
+        newRepoContainer.clean();
+        FileUtils.deleteQuietly(testFolder);
+    }
+}
\ No newline at end of file

Modified: jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/blob/LengthCachingDataStoreTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/blob/LengthCachingDataStoreTest.java?rev=1774571&r1=1774570&r2=1774571&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/blob/LengthCachingDataStoreTest.java (original)
+++ jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/blob/LengthCachingDataStoreTest.java Fri Dec 16 11:12:53 2016
@@ -19,6 +19,10 @@
 
 package org.apache.jackrabbit.oak.upgrade.blob;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
 import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FileOutputStream;
@@ -28,7 +32,7 @@ import java.nio.charset.Charset;
 import java.util.Properties;
 import java.util.Random;
 
-import com.google.common.io.ByteStreams;
+import com.google.common.io.ByteSource;
 import com.google.common.io.Files;
 import com.google.common.io.InputSupplier;
 import org.apache.jackrabbit.core.data.DataIdentifier;
@@ -39,14 +43,10 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
 public class LengthCachingDataStoreTest {
 
     @Rule
-    public final TemporaryFolder tempFolder = new TemporaryFolder();
+    public final TemporaryFolder tempFolder = new TemporaryFolder(new File("target"));
 
     @Test
     public void mappingFileData() throws Exception {
@@ -106,7 +106,7 @@ public class LengthCachingDataStoreTest
         assertEquals(dr, dr2);
 
         assertEquals(dr.getLength(), dr2.getLength());
-        assertTrue(ByteStreams.equal(supplier(dr), supplier(dr2)));
+        assertTrue(supplier(dr).contentEquals(supplier(dr2)));
     }
 
     @Test
@@ -181,10 +181,10 @@ public class LengthCachingDataStoreTest
         return data;
     }
 
-    private static InputSupplier<InputStream> supplier(final DataRecord dr) {
-        return new InputSupplier<InputStream>() {
+    private static ByteSource supplier(final DataRecord dr) {
+        return new ByteSource() {
             @Override
-            public InputStream getInput() throws IOException {
+            public InputStream openStream() throws IOException {
                 try {
                     return dr.getStream();
                 } catch (DataStoreException e) {

Modified: jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/AbstractOak2OakTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/AbstractOak2OakTest.java?rev=1774571&r1=1774570&r2=1774571&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/AbstractOak2OakTest.java (original)
+++ jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/AbstractOak2OakTest.java Fri Dec 16 11:12:53 2016
@@ -16,7 +16,10 @@
  */
 package org.apache.jackrabbit.oak.upgrade.cli;
 
+import static java.util.Collections.singletonMap;
+import static junit.framework.Assert.assertFalse;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
 import java.io.File;
@@ -24,6 +27,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Map;
 
 import javax.annotation.Nullable;
 import javax.jcr.Node;
@@ -36,13 +40,21 @@ import javax.jcr.Value;
 import com.google.common.base.Function;
 import com.google.common.collect.Lists;
 import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.commons.IOUtils;
 import org.apache.jackrabbit.oak.jcr.Jcr;
 import org.apache.jackrabbit.oak.jcr.repository.RepositoryImpl;
 import org.apache.jackrabbit.oak.plugins.index.reference.ReferenceIndexProvider;
+import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeState;
+import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
+import org.apache.jackrabbit.oak.spi.commit.EmptyHook;
+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.apache.jackrabbit.oak.upgrade.RepositorySidegrade;
 import org.apache.jackrabbit.oak.upgrade.cli.container.NodeStoreContainer;
 import org.apache.jackrabbit.oak.upgrade.cli.container.SegmentNodeStoreContainer;
+import org.apache.jackrabbit.oak.upgrade.cli.parser.CliArgumentException;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -64,6 +76,8 @@ public abstract class AbstractOak2OakTes
 
     private RepositoryImpl repository;
 
+    private String checkpointReference;
+
     protected abstract NodeStoreContainer getSourceContainer();
 
     protected abstract NodeStoreContainer getDestinationContainer();
@@ -102,13 +116,21 @@ public abstract class AbstractOak2OakTes
 
     @After
     public void clean() throws IOException {
-        session.logout();
-        repository.shutdown();
-        getDestinationContainer().close();
-        getDestinationContainer().clean();
+        try {
+            if (session != null) {
+                session.logout();
+            }
+            if (repository != null) {
+                repository.shutdown();
+            }
+        } finally {
+            IOUtils.closeQuietly(getDestinationContainer());
+            getDestinationContainer().clean();
+            getSourceContainer().clean();
+        }
     }
 
-    protected void initContent(NodeStore target) throws IOException, RepositoryException {
+    protected void initContent(NodeStore target) throws IOException, RepositoryException, CommitFailedException {
         NodeStore initialContent = testContent.open();
         try {
             RepositorySidegrade sidegrade = new RepositorySidegrade(initialContent, target);
@@ -116,12 +138,26 @@ public abstract class AbstractOak2OakTes
         } finally {
             testContent.close();
         }
+
+        NodeBuilder builder = target.getRoot().builder();
+        builder.setProperty("checkpoint-state", "before");
+        target.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+        checkpointReference = target.checkpoint(60000, singletonMap("key", "123"));
+
+        builder.setProperty("checkpoint-state", "after");
+        builder.child(":async").setProperty("test", "123");
+        target.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
     }
 
     @Test
-    public void validateMigration() throws RepositoryException, IOException {
+    public void validateMigration() throws RepositoryException, IOException, CliArgumentException {
         verifyContent(session);
         verifyBlob(session);
+        if (supportsCheckpointMigration()) {
+            verifyCheckpoint();
+        } else {
+            verifyEmptyAsync();
+        }
     }
 
     public static void verifyContent(Session session) throws RepositoryException {
@@ -165,4 +201,44 @@ public abstract class AbstractOak2OakTes
         }
     }
 
-}
+    private void verifyCheckpoint() {
+        assertEquals("after", destination.getRoot().getString("checkpoint-state"));
+
+        Map<String, String> info = destination.checkpointInfo(checkpointReference);
+        assertEquals("123", info.get("key"));
+
+        NodeState checkpoint = destination.retrieve(checkpointReference);
+        assertEquals("before", checkpoint.getString("checkpoint-state"));
+
+        assertEquals("123", destination.getRoot().getChildNode(":async").getString("test"));
+
+        for (String name : new String[] {"var", "etc", "sling.css", "apps", "libs", "sightly"}) {
+            assertSameRecord(destination.getRoot().getChildNode(name), checkpoint.getChildNode(name));
+        }
+    }
+
+    private static void assertSameRecord(NodeState ns1, NodeState ns2) {
+        String recordId1 = getRecordId(ns1);
+        String recordId2 = getRecordId(ns2);
+        assertNotNull(recordId1);
+        assertEquals(recordId1, recordId2);
+    }
+
+    private static String getRecordId(NodeState node) {
+        if (node instanceof SegmentNodeState) {
+            return ((SegmentNodeState) node).getRecordId().toString();
+        } else {
+            return null;
+        }
+    }
+
+    // OAK-2869
+    private void verifyEmptyAsync() {
+        NodeState state = destination.getRoot().getChildNode(":async");
+        assertFalse(state.hasProperty("test"));
+    }
+
+    protected boolean supportsCheckpointMigration() {
+        return false;
+    }
+}
\ No newline at end of file

Modified: jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/Jcr2ToSegmentTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/Jcr2ToSegmentTest.java?rev=1774571&r1=1774570&r2=1774571&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/Jcr2ToSegmentTest.java (original)
+++ jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/Jcr2ToSegmentTest.java Fri Dec 16 11:12:53 2016
@@ -43,6 +43,9 @@ public class Jcr2ToSegmentTest {
 
     private Session session;
 
+    public Jcr2ToSegmentTest() throws IOException {
+    }
+
     @Before
     public void prepare() throws Exception {
         File tempDir = new File("target", "test-jcr2");

Copied: jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/MongoToMongoFdsTest.java (from r1774499, jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/MongoToMongoFds.java)
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/MongoToMongoFdsTest.java?p2=jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/MongoToMongoFdsTest.java&p1=jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/MongoToMongoFds.java&r1=1774499&r2=1774571&rev=1774571&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/MongoToMongoFds.java (original)
+++ jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/MongoToMongoFdsTest.java Fri Dec 16 11:12:53 2016
@@ -26,7 +26,7 @@ import org.apache.jackrabbit.oak.upgrade
 import org.apache.jackrabbit.oak.upgrade.cli.container.MongoNodeStoreContainer;
 import org.apache.jackrabbit.oak.upgrade.cli.container.NodeStoreContainer;
 
-public class MongoToMongoFds extends AbstractOak2OakTest {
+public class MongoToMongoFdsTest extends AbstractOak2OakTest {
 
     private final BlobStoreContainer destinationBlob;
 
@@ -34,7 +34,7 @@ public class MongoToMongoFds extends Abs
 
     private final NodeStoreContainer destination;
 
-    public MongoToMongoFds() throws IOException {
+    public MongoToMongoFdsTest() throws IOException {
         assumeTrue(isMongoAvailable());
         destinationBlob = new FileDataStoreContainer();
         source = new MongoNodeStoreContainer();
@@ -53,7 +53,7 @@ public class MongoToMongoFds extends Abs
 
     @Override
     protected String[] getArgs() {
-        return new String[] { "--copy-binaries", "--fileblobstore", destinationBlob.getDescription(),
+        return new String[] { "--copy-binaries", "--datastore", destinationBlob.getDescription(),
                 source.getDescription(), destination.getDescription() };
     }
 }

Modified: jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/SegmentToJdbcTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/SegmentToJdbcTest.java?rev=1774571&r1=1774570&r2=1774571&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/SegmentToJdbcTest.java (original)
+++ jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/SegmentToJdbcTest.java Fri Dec 16 11:12:53 2016
@@ -46,7 +46,7 @@ public class SegmentToJdbcTest extends A
 
     @Override
     protected String[] getArgs() {
-        return new String[] { "--user", "sa", "--password", "sa", source.getDescription(),
+        return new String[] { "--disable-mmap", "--user", "sa", "--password", "sa", source.getDescription(),
                 destination.getDescription() };
     }
 }

Modified: jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/SegmentToSegmentTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/SegmentToSegmentTest.java?rev=1774571&r1=1774570&r2=1774571&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/SegmentToSegmentTest.java (original)
+++ jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/SegmentToSegmentTest.java Fri Dec 16 11:12:53 2016
@@ -19,13 +19,15 @@ package org.apache.jackrabbit.oak.upgrad
 import org.apache.jackrabbit.oak.upgrade.cli.container.NodeStoreContainer;
 import org.apache.jackrabbit.oak.upgrade.cli.container.SegmentNodeStoreContainer;
 
+import java.io.IOException;
+
 public class SegmentToSegmentTest extends AbstractOak2OakTest {
 
     private final NodeStoreContainer source;
 
     private final NodeStoreContainer destination;
 
-    public SegmentToSegmentTest() {
+    public SegmentToSegmentTest() throws IOException {
         source = new SegmentNodeStoreContainer();
         destination = new SegmentNodeStoreContainer();
     }
@@ -44,4 +46,9 @@ public class SegmentToSegmentTest extend
     protected String[] getArgs() {
         return new String[] { source.getDescription(), destination.getDescription() };
     }
+
+    @Override
+    protected boolean supportsCheckpointMigration() {
+        return true;
+    }
 }

Copied: jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/SegmentToSegmentWithMissingDestinationDirectoryTest.java (from r1774499, jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/CopyReferencesTest.java)
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/SegmentToSegmentWithMissingDestinationDirectoryTest.java?p2=jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/SegmentToSegmentWithMissingDestinationDirectoryTest.java&p1=jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/CopyReferencesTest.java&r1=1774499&r2=1774571&rev=1774571&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/CopyReferencesTest.java (original)
+++ jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/SegmentToSegmentWithMissingDestinationDirectoryTest.java Fri Dec 16 11:12:53 2016
@@ -14,26 +14,27 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.jackrabbit.oak.upgrade.cli.blob;
+package org.apache.jackrabbit.oak.upgrade.cli;
 
-import org.apache.jackrabbit.oak.upgrade.cli.AbstractOak2OakTest;
-import org.apache.jackrabbit.oak.upgrade.cli.container.BlobStoreContainer;
-import org.apache.jackrabbit.oak.upgrade.cli.container.FileDataStoreContainer;
 import org.apache.jackrabbit.oak.upgrade.cli.container.NodeStoreContainer;
 import org.apache.jackrabbit.oak.upgrade.cli.container.SegmentNodeStoreContainer;
 
-public class CopyReferencesTest extends AbstractOak2OakTest {
-
-    private final BlobStoreContainer sourceBlob;
+import java.io.IOException;
 
+public class SegmentToSegmentWithMissingDestinationDirectoryTest extends AbstractOak2OakTest {
     private final NodeStoreContainer source;
 
     private final NodeStoreContainer destination;
 
-    public CopyReferencesTest() {
-        sourceBlob = new FileDataStoreContainer();
-        source = new SegmentNodeStoreContainer(sourceBlob);
-        destination = new SegmentNodeStoreContainer(sourceBlob);
+    public SegmentToSegmentWithMissingDestinationDirectoryTest() throws IOException {
+        source = new SegmentNodeStoreContainer();
+        destination = getSegmentNodeStoreContainerWithMissingDirectory();
+    }
+
+    private SegmentNodeStoreContainer getSegmentNodeStoreContainerWithMissingDirectory() throws IOException {
+        SegmentNodeStoreContainer segmentNodeStoreContainer = new SegmentNodeStoreContainer();
+        segmentNodeStoreContainer.getDirectory().delete();
+        return segmentNodeStoreContainer;
     }
 
     @Override
@@ -48,7 +49,12 @@ public class CopyReferencesTest extends
 
     @Override
     protected String[] getArgs() {
-        return new String[] { "--src-datastore", sourceBlob.getDescription(), source.getDescription(),
-                destination.getDescription() };
+        return new String[] { source.getDescription(), destination.getDescription() };
     }
+
+    @Override
+    protected boolean supportsCheckpointMigration() {
+        return true;
+    }
+
 }

Added: jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/CopyBinariesTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/CopyBinariesTest.java?rev=1774571&view=auto
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/CopyBinariesTest.java (added)
+++ jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/CopyBinariesTest.java Fri Dec 16 11:12:53 2016
@@ -0,0 +1,201 @@
+/*
+ * 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.cli.blob;
+
+import static java.util.Arrays.asList;
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import com.google.common.base.Joiner;
+import org.apache.jackrabbit.oak.spi.state.NodeStore;
+import org.apache.jackrabbit.oak.upgrade.cli.AbstractOak2OakTest;
+import org.apache.jackrabbit.oak.upgrade.cli.OakUpgrade;
+import org.apache.jackrabbit.oak.upgrade.cli.container.BlobStoreContainer;
+import org.apache.jackrabbit.oak.upgrade.cli.container.FileDataStoreContainer;
+import org.apache.jackrabbit.oak.upgrade.cli.container.JdbcNodeStoreContainer;
+import org.apache.jackrabbit.oak.upgrade.cli.container.NodeStoreContainer;
+import org.apache.jackrabbit.oak.upgrade.cli.container.SegmentNodeStoreContainer;
+import org.apache.jackrabbit.oak.upgrade.cli.parser.CliArgumentException;
+import org.apache.jackrabbit.oak.upgrade.cli.parser.DatastoreArguments;
+import org.apache.jackrabbit.oak.upgrade.cli.parser.MigrationCliArguments;
+import org.apache.jackrabbit.oak.upgrade.cli.parser.MigrationOptions;
+import org.apache.jackrabbit.oak.upgrade.cli.parser.OptionParserFactory;
+import org.apache.jackrabbit.oak.upgrade.cli.parser.StoreArguments;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.jcr.RepositoryException;
+
+@RunWith(Parameterized.class)
+public class CopyBinariesTest extends AbstractOak2OakTest {
+
+    private static final Logger log = LoggerFactory.getLogger(CopyBinariesTest.class);
+
+    @Parameterized.Parameters(name = "{0}")
+    public static Collection<Object[]> data() throws IOException {
+        List<Object[]> params = new ArrayList<Object[]>();
+
+        BlobStoreContainer blob = new FileDataStoreContainer();
+        BlobStoreContainer blob2 = new FileDataStoreContainer();
+        params.add(new Object[]{
+                "Copy references, no blobstores defined, segment -> segment",
+                new SegmentNodeStoreContainer(blob),
+                new SegmentNodeStoreContainer(blob),
+                asList(),
+                DatastoreArguments.BlobMigrationCase.COPY_REFERENCES
+        });
+        params.add(new Object[]{
+                "Copy references, no blobstores defined, document -> segment",
+                new JdbcNodeStoreContainer(blob),
+                new SegmentNodeStoreContainer(blob),
+                asList("--src-user=sa", "--src-password=sa"),
+                DatastoreArguments.BlobMigrationCase.COPY_REFERENCES
+        });
+        params.add(new Object[]{
+                "Copy references, no blobstores defined, segment -> document",
+                new SegmentNodeStoreContainer(blob),
+                new JdbcNodeStoreContainer(blob),
+                asList("--user=sa", "--password=sa"),
+                DatastoreArguments.BlobMigrationCase.UNSUPPORTED
+        });
+        params.add(new Object[]{
+                "Missing source, external destination",
+                new SegmentNodeStoreContainer(blob),
+                new SegmentNodeStoreContainer(blob),
+                asList("--datastore=" + blob.getDescription()),
+                DatastoreArguments.BlobMigrationCase.UNSUPPORTED
+        });
+        params.add(new Object[]{
+                "Copy embedded to embedded, no blobstores defined",
+                new SegmentNodeStoreContainer(),
+                new SegmentNodeStoreContainer(),
+                asList(),
+                DatastoreArguments.BlobMigrationCase.EMBEDDED_TO_EMBEDDED
+        });
+        params.add(new Object[]{
+                "Copy embedded to external, no blobstores defined",
+                new SegmentNodeStoreContainer(),
+                new SegmentNodeStoreContainer(blob),
+                asList("--datastore=" + blob.getDescription()),
+                DatastoreArguments.BlobMigrationCase.EMBEDDED_TO_EXTERNAL
+        });
+        params.add(new Object[]{
+                "Copy references, src blobstore defined",
+                new SegmentNodeStoreContainer(blob),
+                new SegmentNodeStoreContainer(blob),
+                asList("--src-datastore=" + blob.getDescription()),
+                DatastoreArguments.BlobMigrationCase.COPY_REFERENCES
+        });
+        params.add(new Object[]{
+                "Copy external to embedded, src blobstore defined",
+                new SegmentNodeStoreContainer(blob),
+                new SegmentNodeStoreContainer(),
+                asList("--copy-binaries", "--src-datastore=" + blob.getDescription()),
+                DatastoreArguments.BlobMigrationCase.EXTERNAL_TO_EMBEDDED
+        });
+        params.add(new Object[]{
+                "Copy external to external, src blobstore defined",
+                new SegmentNodeStoreContainer(blob),
+                new SegmentNodeStoreContainer(blob2),
+                asList("--copy-binaries", "--src-datastore=" + blob.getDescription(), "--datastore=" + blob2.getDescription()),
+                DatastoreArguments.BlobMigrationCase.EXTERNAL_TO_EXTERNAL
+        });
+        return params;
+    }
+
+    private final NodeStoreContainer source;
+
+    private final NodeStoreContainer destination;
+
+    private final List<String> args;
+
+    private final DatastoreArguments.BlobMigrationCase blobMigrationCase;
+
+    public CopyBinariesTest(String name, NodeStoreContainer source, NodeStoreContainer destination, List<String> args, DatastoreArguments.BlobMigrationCase blobMigrationCase) throws IOException, CliArgumentException {
+        this.source = source;
+        this.destination = destination;
+        this.args = args;
+        this.blobMigrationCase = blobMigrationCase;
+
+        this.source.clean();
+        this.destination.clean();
+    }
+
+    @Override
+    protected NodeStoreContainer getSourceContainer() {
+        return source;
+    }
+
+    @Override
+    protected NodeStoreContainer getDestinationContainer() {
+        return destination;
+    }
+
+    @Override
+    protected String[] getArgs() {
+        List<String> result = new ArrayList<>(args);
+        result.addAll(asList("--disable-mmap", source.getDescription(), destination.getDescription()));
+        return result.toArray(new String[result.size()]);
+    }
+
+    @Before
+    @Override
+    public void prepare() throws Exception {
+        NodeStore source = getSourceContainer().open();
+        try {
+            initContent(source);
+        } finally {
+            getSourceContainer().close();
+        }
+
+        String[] args = getArgs();
+        log.info("oak2oak {}", Joiner.on(' ').join(args));
+        try {
+            MigrationCliArguments cliArgs = new MigrationCliArguments(OptionParserFactory.create().parse(args));
+            MigrationOptions options = new MigrationOptions(cliArgs);
+            StoreArguments stores = new StoreArguments(options, cliArgs.getArguments());
+            DatastoreArguments datastores = new DatastoreArguments(options, stores, stores.srcUsesEmbeddedDatastore());
+            OakUpgrade.migrate(options, stores, datastores);
+            assertEquals(blobMigrationCase, datastores.getBlobMigrationCase());
+        } catch(CliArgumentException e) {
+            if (blobMigrationCase == DatastoreArguments.BlobMigrationCase.UNSUPPORTED) {
+                return;
+            } else {
+                throw e;
+            }
+        }
+        createSession();
+    }
+
+    @Test
+    @Override
+    public void validateMigration() throws RepositoryException, IOException, CliArgumentException {
+        if (blobMigrationCase == DatastoreArguments.BlobMigrationCase.UNSUPPORTED) {
+            return;
+        }
+        verifyContent(session);
+        verifyBlob(session);
+    }
+}
\ No newline at end of file

Modified: jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FbsToFbsTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FbsToFbsTest.java?rev=1774571&r1=1774570&r2=1774571&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FbsToFbsTest.java (original)
+++ jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FbsToFbsTest.java Fri Dec 16 11:12:53 2016
@@ -22,6 +22,8 @@ import org.apache.jackrabbit.oak.upgrade
 import org.apache.jackrabbit.oak.upgrade.cli.container.NodeStoreContainer;
 import org.apache.jackrabbit.oak.upgrade.cli.container.SegmentNodeStoreContainer;
 
+import java.io.IOException;
+
 public class FbsToFbsTest extends AbstractOak2OakTest {
 
     private final BlobStoreContainer sourceBlob;
@@ -32,7 +34,7 @@ public class FbsToFbsTest extends Abstra
 
     private final NodeStoreContainer destination;
 
-    public FbsToFbsTest() {
+    public FbsToFbsTest() throws IOException {
         sourceBlob = new FileBlobStoreContainer();
         destinationBlob = new FileBlobStoreContainer();
         source = new SegmentNodeStoreContainer(sourceBlob);
@@ -54,4 +56,9 @@ public class FbsToFbsTest extends Abstra
         return new String[] { "--copy-binaries", "--src-fileblobstore", sourceBlob.getDescription(), "--fileblobstore",
                 destinationBlob.getDescription(), source.getDescription(), destination.getDescription() };
     }
+
+    @Override
+    protected boolean supportsCheckpointMigration() {
+        return true;
+    }
 }

Modified: jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FbsToFdsTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FbsToFdsTest.java?rev=1774571&r1=1774570&r2=1774571&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FbsToFdsTest.java (original)
+++ jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FbsToFdsTest.java Fri Dec 16 11:12:53 2016
@@ -23,6 +23,8 @@ import org.apache.jackrabbit.oak.upgrade
 import org.apache.jackrabbit.oak.upgrade.cli.container.NodeStoreContainer;
 import org.apache.jackrabbit.oak.upgrade.cli.container.SegmentNodeStoreContainer;
 
+import java.io.IOException;
+
 public class FbsToFdsTest extends AbstractOak2OakTest {
 
     private final BlobStoreContainer sourceBlob;
@@ -33,7 +35,7 @@ public class FbsToFdsTest extends Abstra
 
     private final NodeStoreContainer destination;
 
-    public FbsToFdsTest() {
+    public FbsToFdsTest() throws IOException {
         sourceBlob = new FileBlobStoreContainer();
         destinationBlob = new FileDataStoreContainer();
         source = new SegmentNodeStoreContainer(sourceBlob);
@@ -55,4 +57,9 @@ public class FbsToFdsTest extends Abstra
         return new String[] { "--copy-binaries", "--src-fileblobstore", sourceBlob.getDescription(), "--datastore",
                 destinationBlob.getDescription(), source.getDescription(), destination.getDescription() };
     }
+
+    @Override
+    protected boolean supportsCheckpointMigration() {
+        return true;
+    }
 }

Modified: jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FbsToS3Test.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FbsToS3Test.java?rev=1774571&r1=1774570&r2=1774571&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FbsToS3Test.java (original)
+++ jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FbsToS3Test.java Fri Dec 16 11:12:53 2016
@@ -62,4 +62,9 @@ public class FbsToS3Test extends Abstrac
                 destinationBlob.getDescription(), "--s3config", S3_PROPERTIES, source.getDescription(),
                 destination.getDescription() };
     }
+
+    @Override
+    protected boolean supportsCheckpointMigration() {
+        return true;
+    }
 }

Modified: jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FdsToFbsTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FdsToFbsTest.java?rev=1774571&r1=1774570&r2=1774571&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FdsToFbsTest.java (original)
+++ jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FdsToFbsTest.java Fri Dec 16 11:12:53 2016
@@ -23,6 +23,8 @@ import org.apache.jackrabbit.oak.upgrade
 import org.apache.jackrabbit.oak.upgrade.cli.container.NodeStoreContainer;
 import org.apache.jackrabbit.oak.upgrade.cli.container.SegmentNodeStoreContainer;
 
+import java.io.IOException;
+
 public class FdsToFbsTest extends AbstractOak2OakTest {
 
     private final BlobStoreContainer sourceBlob;
@@ -33,7 +35,7 @@ public class FdsToFbsTest extends Abstra
 
     private final NodeStoreContainer destination;
 
-    public FdsToFbsTest() {
+    public FdsToFbsTest() throws IOException {
         sourceBlob = new FileDataStoreContainer();
         destinationBlob = new FileBlobStoreContainer();
         source = new SegmentNodeStoreContainer(sourceBlob);
@@ -55,4 +57,9 @@ public class FdsToFbsTest extends Abstra
         return new String[] { "--copy-binaries", "--src-datastore", sourceBlob.getDescription(), "--fileblobstore",
                 destinationBlob.getDescription(), source.getDescription(), destination.getDescription() };
     }
+
+    @Override
+    protected boolean supportsCheckpointMigration() {
+        return true;
+    }
 }

Modified: jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/S3ToFbsTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/S3ToFbsTest.java?rev=1774571&r1=1774570&r2=1774571&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/S3ToFbsTest.java (original)
+++ jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/S3ToFbsTest.java Fri Dec 16 11:12:53 2016
@@ -62,4 +62,9 @@ public class S3ToFbsTest extends Abstrac
                 S3_PROPERTIES, "--fileblobstore", destinationBlob.getDescription(), source.getDescription(),
                 destination.getDescription() };
     }
+
+    @Override
+    protected boolean supportsCheckpointMigration() {
+        return true;
+    }
 }

Modified: jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/FileBlobStoreContainer.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/FileBlobStoreContainer.java?rev=1774571&r1=1774570&r2=1774571&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/FileBlobStoreContainer.java (original)
+++ jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/FileBlobStoreContainer.java Fri Dec 16 11:12:53 2016
@@ -18,19 +18,19 @@ package org.apache.jackrabbit.oak.upgrad
 
 import java.io.File;
 import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 
 import org.apache.commons.io.FileUtils;
 import org.apache.jackrabbit.oak.spi.blob.BlobStore;
 import org.apache.jackrabbit.oak.spi.blob.FileBlobStore;
 
-import com.google.common.io.Files;
-
 public class FileBlobStoreContainer implements BlobStoreContainer {
 
     private final File directory;
 
-    public FileBlobStoreContainer() {
-        this.directory = Files.createTempDir();
+    public FileBlobStoreContainer() throws IOException {
+        this.directory = Files.createTempDirectory(Paths.get("target"), "repo-fbs").toFile();
     }
 
     @Override
@@ -44,7 +44,7 @@ public class FileBlobStoreContainer impl
 
     @Override
     public void clean() throws IOException {
-        FileUtils.deleteDirectory(directory);
+        FileUtils.deleteQuietly(directory);
     }
 
     @Override

Modified: jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/FileDataStoreContainer.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/FileDataStoreContainer.java?rev=1774571&r1=1774570&r2=1774571&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/FileDataStoreContainer.java (original)
+++ jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/FileDataStoreContainer.java Fri Dec 16 11:12:53 2016
@@ -18,13 +18,14 @@ package org.apache.jackrabbit.oak.upgrad
 
 import java.io.File;
 import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 
 import org.apache.commons.io.FileUtils;
 import org.apache.jackrabbit.oak.spi.blob.BlobStore;
 import org.apache.jackrabbit.oak.upgrade.cli.blob.FileDataStoreFactory;
 
 import com.google.common.io.Closer;
-import com.google.common.io.Files;
 
 public class FileDataStoreContainer implements BlobStoreContainer {
 
@@ -32,8 +33,8 @@ public class FileDataStoreContainer impl
 
     private final Closer closer;
     
-    public FileDataStoreContainer() {
-        this.directory = Files.createTempDir();
+    public FileDataStoreContainer() throws IOException {
+        this.directory = Files.createTempDirectory(Paths.get("target"), "repo-fds").toFile();
         this.closer = Closer.create();
     }
 
@@ -49,7 +50,7 @@ public class FileDataStoreContainer impl
 
     @Override
     public void clean() throws IOException {
-        FileUtils.deleteDirectory(directory);
+        FileUtils.deleteQuietly(directory);
     }
 
     @Override

Modified: jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/JdbcNodeStoreContainer.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/JdbcNodeStoreContainer.java?rev=1774571&r1=1774570&r2=1774571&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/JdbcNodeStoreContainer.java (original)
+++ jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/JdbcNodeStoreContainer.java Fri Dec 16 11:12:53 2016
@@ -18,6 +18,8 @@ package org.apache.jackrabbit.oak.upgrad
 
 import java.io.File;
 import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 
 import org.apache.commons.io.FileUtils;
 import org.apache.jackrabbit.oak.spi.state.NodeStore;
@@ -26,7 +28,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.io.Closer;
-import com.google.common.io.Files;
 
 public class JdbcNodeStoreContainer implements NodeStoreContainer {
 
@@ -46,11 +47,11 @@ public class JdbcNodeStoreContainer impl
         this(new DummyBlobStoreContainer());
     }
 
-    public JdbcNodeStoreContainer(BlobStoreContainer blob) {
+    public JdbcNodeStoreContainer(BlobStoreContainer blob) throws IOException {
         this.blob = blob;
-        this.h2Dir = Files.createTempDir();
-        this.jdbcUri = String.format("jdbc:h2:%s", h2Dir.getPath());
-        this.jdbcFactory = new JdbcFactory(jdbcUri, 2, "sa", "sa");
+        this.h2Dir = Files.createTempDirectory(Paths.get("target"), "repo-h2").toFile();
+        this.jdbcUri = String.format("jdbc:h2:%s", h2Dir.getAbsolutePath() + "/JdbcNodeStoreContainer");
+        this.jdbcFactory = new JdbcFactory(jdbcUri, 2, "sa", "sa", false);
     }
 
     @Override
@@ -62,7 +63,10 @@ public class JdbcNodeStoreContainer impl
     @Override
     public void close() {
         try {
-            closer.close();
+            if (closer != null) {
+                closer.close();
+                closer = null;
+            }
         } catch (IOException e) {
             LOG.error("Can't close document node store", e);
         }
@@ -70,7 +74,7 @@ public class JdbcNodeStoreContainer impl
 
     @Override
     public void clean() throws IOException {
-        FileUtils.deleteDirectory(h2Dir);
+        FileUtils.deleteQuietly(h2Dir);
         blob.clean();
     }
 

Modified: jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/MongoNodeStoreContainer.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/MongoNodeStoreContainer.java?rev=1774571&r1=1774570&r2=1774571&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/MongoNodeStoreContainer.java (original)
+++ jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/MongoNodeStoreContainer.java Fri Dec 16 11:12:53 2016
@@ -56,7 +56,7 @@ public class MongoNodeStoreContainer imp
     public MongoNodeStoreContainer(BlobStoreContainer blob) throws IOException {
         Assume.assumeTrue(isMongoAvailable());
         this.mongoUri = String.format("%s-%d", MONGO_URI, DATABASE_SUFFIX.getAndIncrement());
-        this.mongoFactory = new MongoFactory(mongoUri, 2);
+        this.mongoFactory = new MongoFactory(mongoUri, 2, false);
         this.blob = blob;
         clean();
     }

Modified: jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/S3DataStoreContainer.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/S3DataStoreContainer.java?rev=1774571&r1=1774570&r2=1774571&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/S3DataStoreContainer.java (original)
+++ jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/S3DataStoreContainer.java Fri Dec 16 11:12:53 2016
@@ -18,6 +18,8 @@ package org.apache.jackrabbit.oak.upgrad
 
 import java.io.File;
 import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 
 import org.apache.commons.io.FileUtils;
 import org.apache.jackrabbit.oak.spi.blob.BlobStore;
@@ -26,7 +28,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.io.Closer;
-import com.google.common.io.Files;
 
 public class S3DataStoreContainer implements BlobStoreContainer {
 
@@ -39,7 +40,7 @@ public class S3DataStoreContainer implem
     private final Closer closer;
 
     public S3DataStoreContainer(String configFile) throws IOException {
-        this.directory = Files.createTempDir();
+        this.directory = Files.createTempDirectory(Paths.get("target"), "repo-s3").toFile();
         this.factory = new S3DataStoreFactory(configFile, directory.getPath(), false);
         this.closer = Closer.create();
     }
@@ -60,7 +61,7 @@ public class S3DataStoreContainer implem
 
     @Override
     public void clean() throws IOException {
-        FileUtils.deleteDirectory(directory);
+        FileUtils.deleteQuietly(directory);
     }
 
     @Override

Modified: jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/SegmentNodeStoreContainer.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/SegmentNodeStoreContainer.java?rev=1774571&r1=1774570&r2=1774571&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/SegmentNodeStoreContainer.java (original)
+++ jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/SegmentNodeStoreContainer.java Fri Dec 16 11:12:53 2016
@@ -18,14 +18,14 @@ package org.apache.jackrabbit.oak.upgrad
 
 import java.io.File;
 import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 
 import org.apache.commons.io.FileUtils;
 import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeStore;
 import org.apache.jackrabbit.oak.plugins.segment.file.FileStore;
 import org.apache.jackrabbit.oak.spi.state.NodeStore;
 
-import com.google.common.io.Files;
-
 public class SegmentNodeStoreContainer implements NodeStoreContainer {
 
     private final File directory;
@@ -34,22 +34,26 @@ public class SegmentNodeStoreContainer i
 
     private FileStore fs;
 
-    public SegmentNodeStoreContainer() {
-        this(Files.createTempDir());
+    public SegmentNodeStoreContainer() throws IOException {
+        this(null, null);
+    }
+
+    public SegmentNodeStoreContainer(File directory) throws IOException {
+        this(null, directory);
     }
 
-    public SegmentNodeStoreContainer(File directory) {
-        this.blob = null;
-        this.directory = directory;
+    public SegmentNodeStoreContainer(BlobStoreContainer blob) throws IOException {
+        this(blob, null);
     }
 
-    public SegmentNodeStoreContainer(BlobStoreContainer blob) {
+    private SegmentNodeStoreContainer(BlobStoreContainer blob, File directory) throws IOException {
         this.blob = blob;
-        this.directory = Files.createTempDir();
+        this.directory = directory == null ? Files.createTempDirectory(Paths.get("target"), "repo-segment").toFile() : directory;
     }
 
     @Override
     public NodeStore open() throws IOException {
+        directory.mkdirs();
         FileStore.Builder builder = FileStore.newFileStore(new File(directory, "segmentstore"));
         if (blob != null) {
             builder.withBlobStore(blob.open());
@@ -60,12 +64,14 @@ public class SegmentNodeStoreContainer i
 
     @Override
     public void close() {
-        fs.close();
+        if (fs != null) {
+            fs.close();
+        }
     }
 
     @Override
     public void clean() throws IOException {
-        FileUtils.deleteDirectory(directory);
+        FileUtils.deleteQuietly(directory);
         if (blob != null) {
             blob.clean();
         }
@@ -76,4 +82,7 @@ public class SegmentNodeStoreContainer i
         return directory.getPath();
     }
 
+    public File getDirectory() {
+        return directory;
+    }
 }

Copied: jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/parser/StoreArgumentsTest.java (from r1774499, jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java)
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/parser/StoreArgumentsTest.java?p2=jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/parser/StoreArgumentsTest.java&p1=jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java&r1=1774499&r2=1774571&rev=1774571&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java (original)
+++ jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/parser/StoreArgumentsTest.java Fri Dec 16 11:12:53 2016
@@ -14,16 +14,16 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.jackrabbit.oak.upgrade.cli.node;
+package org.apache.jackrabbit.oak.upgrade.cli.parser;
 
-import java.io.IOException;
+import org.junit.Test;
 
-import org.apache.jackrabbit.oak.spi.blob.BlobStore;
-import org.apache.jackrabbit.oak.spi.state.NodeStore;
+public class StoreArgumentsTest {
 
-import com.google.common.io.Closer;
-
-public interface NodeStoreFactory {
-
-    NodeStore create(BlobStore blobStore, Closer closer) throws IOException;
+    @Test(expected =  CliArgumentException.class)
+    public void testSameRepositoryFails() throws CliArgumentException {
+        MigrationCliArguments parsed = new MigrationCliArguments(OptionParserFactory.create().parse("my/repo", "my/repo"));
+        MigrationOptions options = new MigrationOptions(parsed);
+        new StoreArguments(options, parsed.getArguments());
+    }
 }

Added: jackrabbit/oak/branches/1.4/oak-upgrade/src/test/resources/test-repo-1.0.zip
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/test/resources/test-repo-1.0.zip?rev=1774571&view=auto
==============================================================================
Binary files jackrabbit/oak/branches/1.4/oak-upgrade/src/test/resources/test-repo-1.0.zip (added) and jackrabbit/oak/branches/1.4/oak-upgrade/src/test/resources/test-repo-1.0.zip Fri Dec 16 11:12:53 2016 differ