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 2017/03/14 09:38:37 UTC

svn commit: r1786864 - in /jackrabbit/oak/branches/1.6: oak-doc/src/site/markdown/ oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/ oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/ oak-upgrade/src/main/java/org/apache/jackra...

Author: tomekr
Date: Tue Mar 14 09:38:37 2017
New Revision: 1786864

URL: http://svn.apache.org/viewvc?rev=1786864&view=rev
Log:
OAK-5920 Checkpoint migration will fail if the MissingBlobStore is used

Added:
    jackrabbit/oak/branches/1.6/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/CopyCheckpointsTest.java
      - copied, changed from r1786171, jackrabbit/oak/branches/1.6/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/CopyBinariesTest.java
Modified:
    jackrabbit/oak/branches/1.6/oak-doc/src/site/markdown/migration.md
    jackrabbit/oak/branches/1.6/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegrade.java
    jackrabbit/oak/branches/1.6/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/MigrationFactory.java
    jackrabbit/oak/branches/1.6/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/MigrationOptions.java
    jackrabbit/oak/branches/1.6/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/OptionParserFactory.java
    jackrabbit/oak/branches/1.6/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/AbstractOak2OakTest.java
    jackrabbit/oak/branches/1.6/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/CopyBinariesTest.java
    jackrabbit/oak/branches/1.6/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/SegmentNodeStoreContainer.java

Modified: jackrabbit/oak/branches/1.6/oak-doc/src/site/markdown/migration.md
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.6/oak-doc/src/site/markdown/migration.md?rev=1786864&r1=1786863&r2=1786864&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.6/oak-doc/src/site/markdown/migration.md (original)
+++ jackrabbit/oak/branches/1.6/oak-doc/src/site/markdown/migration.md Tue Mar 14 09:38:37 2017
@@ -38,6 +38,7 @@ The `oak-upgrade` module allows to do an
 The `source` and `destination` are the node store paths/URIs. Following node stores are supported:
 
 * `SegmentNodeStore` - use a path to the `repository` directory,
+* old `SegmentNodeStore` (Oak < 1.6) - use the `segment-old:` prefix and the path to the `repository` directory,
 * `DocumentNodeStore` with MongoDB - `mongodb://host:port/database`,
 * `DocumentNodeStore` with a RDB - `jdbc:...`. It requires passing user and password with separate parameters.
 
@@ -207,6 +208,21 @@ A custom `RepositoryInitializer` can be
 
 The full list of supported parameters can be displayed using `--help` switch.
 
+### Checkpoints migration
+
+When migrating an old SegmentMK repository (pre-Oak 1.6) to the new SegmentMK (Oak >= 1.6), the checkpoints are migrated as well. This allows to avoid reindexing when the Oak is being run for the first time on the new repository. However, the checkpoints won't be migrated in following cases:
+
+* custom include-, exclude- or merge- paths are specified or
+* the binaries are copied by references, no source datastore is specified and two different checkpoints contains different binary under the same path.
+
+In the second case oak-upgrade emits following warning and breaks:
+
+    Checkpoints won't be copied, because no external datastore has been specified. This will result in the full repository reindexing on the first start. Use --skip-checkpoints to force the migration or see https://jackrabbit.apache.org/oak/docs/migration.html#Checkpoints_migration for more info.
+
+The easiest way to fix this issue is specifying the source datastore in the command line options (eg. `--src-datastore` or `--src-s3datastore`).
+
+The warning may also be ignored, but in this case the repository will be fully reindexed on the first startup. It may be a long process, especially for the big instance. Repository won't be usable until the reindexing process is done. Use `--skip-checkpoints` option to suppress the warning. 
+
 ## Online blob migration with SplitBlobStore
 
 Oak offers one more way to migrate blob store, without turning off the instance (a few restarts might be required, but the migration process is done during normal repository operation).

Modified: jackrabbit/oak/branches/1.6/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegrade.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.6/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegrade.java?rev=1786864&r1=1786863&r2=1786864&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.6/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegrade.java (original)
+++ jackrabbit/oak/branches/1.6/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegrade.java Tue Mar 14 09:38:37 2017
@@ -103,6 +103,8 @@ public class RepositorySidegrade {
      */
     private Set<String> mergePaths = DEFAULT_MERGE_PATHS;
 
+    private boolean skipCheckpoints = false;
+
     private boolean includeIndex = false;
 
     private boolean filterLongNames = true;
@@ -233,6 +235,10 @@ public class RepositorySidegrade {
         this.onlyVerify = onlyVerify;
     }
 
+    public void setSkipCheckpoints(boolean skipCheckpoints) {
+        this.skipCheckpoints = skipCheckpoints;
+    }
+
     /**
      * Same as {@link #copy(RepositoryInitializer)}, but with no custom initializer.
      *
@@ -304,8 +310,17 @@ public class RepositorySidegrade {
         if (!isCompleteMigration()) {
             LOG.info("Custom paths have been specified, checkpoints won't be migrated");
             isRemoveCheckpointReferences = true;
+        } else if (skipCheckpoints) {
+            LOG.info("Checkpoints won't be migrated because of the --skip-checkpoints option");
+            isRemoveCheckpointReferences = true;
         } else {
-            boolean checkpointsCopied = copyCheckpoints(targetRoot);
+            boolean checkpointsCopied;
+            try {
+                checkpointsCopied = copyCheckpoints(targetRoot);
+            } catch(UnsupportedOperationException e) {
+                removeCheckpoints();
+                throw new RepositoryException("Checkpoints won't be copied, because no external datastore has been specified. This will result in the full repository reindexing on the first start. Use --skip-checkpoints to force the migration or see https://jackrabbit.apache.org/oak/docs/migration.html#Checkpoints_migration for more info.");
+            }
             if (!checkpointsCopied) {
                 LOG.info("Copying checkpoints is not supported for this combination of node stores");
                 isRemoveCheckpointReferences = true;
@@ -409,6 +424,16 @@ public class RepositorySidegrade {
         return true;
    }
 
+    private void removeCheckpoints() {
+        if (!(target instanceof TarNodeStore)) {
+            return;
+        }
+        TarNodeStore targetTarNS = (TarNodeStore) target;
+        NodeBuilder targetSuperRoot = ((TarNodeStore) target).getSuperRoot().builder();
+        targetSuperRoot.setChildNode("checkpoints");
+        targetTarNS.setSuperRoot(targetSuperRoot);
+    }
+
     /**
      * Return all checkpoint paths, sorted by their "created" property, descending.
      *

Modified: jackrabbit/oak/branches/1.6/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/MigrationFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.6/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/MigrationFactory.java?rev=1786864&r1=1786863&r2=1786864&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.6/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/MigrationFactory.java (original)
+++ jackrabbit/oak/branches/1.6/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/MigrationFactory.java Tue Mar 14 09:38:37 2017
@@ -117,6 +117,7 @@ public class MigrationFactory {
         sidegrade.setIncludeIndex(options.isIncludeIndex());
         sidegrade.setVerify(options.isVerify());
         sidegrade.setOnlyVerify(options.isOnlyVerify());
+        sidegrade.setSkipCheckpoints(options.isSkipCheckpoints());
         return sidegrade;
     }
 

Modified: jackrabbit/oak/branches/1.6/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/MigrationOptions.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.6/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/MigrationOptions.java?rev=1786864&r1=1786863&r2=1786864&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.6/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/MigrationOptions.java (original)
+++ jackrabbit/oak/branches/1.6/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/MigrationOptions.java Tue Mar 14 09:38:37 2017
@@ -64,6 +64,8 @@ public class MigrationOptions {
 
     private final boolean onlyVerify;
 
+    private final boolean skipCheckpoints;
+
     private final String srcUser;
 
     private final String srcPassword;
@@ -122,6 +124,7 @@ public class MigrationOptions {
         this.ignoreMissingBinaries = args.hasOption(OptionParserFactory.IGNORE_MISSING_BINARIES);
         this.verify = args.hasOption(OptionParserFactory.VERIFY);
         this.onlyVerify = args.hasOption(OptionParserFactory.ONLY_VERIFY);
+        this.skipCheckpoints = args.hasOption(OptionParserFactory.SKIP_CHECKPOINTS);
 
         this.srcUser = args.getOption(OptionParserFactory.SRC_USER);
         this.srcPassword = args.getOption(OptionParserFactory.SRC_USER);
@@ -210,6 +213,10 @@ public class MigrationOptions {
         return onlyVerify;
     }
 
+    public boolean isSkipCheckpoints() {
+        return skipCheckpoints;
+    }
+
     public String getSrcUser() {
         return srcUser;
     }
@@ -343,6 +350,10 @@ public class MigrationOptions {
             log.info("Source DataStore external blobs: {}", srcExternalBlobs);
         }
 
+        if (skipCheckpoints) {
+            log.info("Checkpoints won't be migrated");
+        }
+
         log.info("Cache size: {} MB", cacheSizeInMB);
 
     }

Modified: jackrabbit/oak/branches/1.6/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/OptionParserFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.6/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/OptionParserFactory.java?rev=1786864&r1=1786863&r2=1786864&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.6/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/OptionParserFactory.java (original)
+++ jackrabbit/oak/branches/1.6/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/OptionParserFactory.java Tue Mar 14 09:38:37 2017
@@ -82,6 +82,8 @@ public class OptionParserFactory {
 
     public static final String ONLY_VERIFY = "only-verify";
 
+    public static final String SKIP_CHECKPOINTS = "skip-checkpoints";
+
     public static OptionParser create() {
         OptionParser op = new OptionParser();
         addUsageOptions(op);
@@ -153,5 +155,6 @@ public class OptionParserFactory {
         op.accepts(SKIP_NAME_CHECK, "Skip the initial phase of testing node name lengths");
         op.accepts(VERIFY, "After the sidegrade check whether the source repository is exactly the same as destination");
         op.accepts(ONLY_VERIFY, "Performs only --" + VERIFY + ", without copying content");
+        op.accepts(SKIP_CHECKPOINTS, "Don't copy checkpoints on the full segment->segment migration");
     }
 }

Copied: jackrabbit/oak/branches/1.6/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/CopyCheckpointsTest.java (from r1786171, jackrabbit/oak/branches/1.6/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/CopyBinariesTest.java)
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.6/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/CopyCheckpointsTest.java?p2=jackrabbit/oak/branches/1.6/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/CopyCheckpointsTest.java&p1=jackrabbit/oak/branches/1.6/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/CopyBinariesTest.java&r1=1786171&r2=1786864&rev=1786864&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.6/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/CopyBinariesTest.java (original)
+++ jackrabbit/oak/branches/1.6/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/CopyCheckpointsTest.java Tue Mar 14 09:38:37 2017
@@ -14,15 +14,7 @@
  * 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;
+package org.apache.jackrabbit.oak.upgrade;
 
 import com.google.common.base.Joiner;
 import org.apache.jackrabbit.oak.spi.state.NodeStore;
@@ -30,7 +22,6 @@ import org.apache.jackrabbit.oak.upgrade
 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.container.SegmentTarNodeStoreContainer;
@@ -40,6 +31,7 @@ import org.apache.jackrabbit.oak.upgrade
 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.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -48,87 +40,48 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.jcr.RepositoryException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import static java.util.Arrays.asList;
+import static org.junit.Assert.fail;
 
 @RunWith(Parameterized.class)
-public class CopyBinariesTest extends AbstractOak2OakTest {
+public class CopyCheckpointsTest extends AbstractOak2OakTest {
 
-    private static final Logger log = LoggerFactory.getLogger(CopyBinariesTest.class);
+    private enum Result {
+        EXCEPTION, CHECKPOINTS_MISSING, CHECKPOINTS_COPIED
+    }
+
+    private static final Logger log = LoggerFactory.getLogger(CopyCheckpointsTest.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",
+                "Fails on missing blobstore",
                 new SegmentNodeStoreContainer(blob),
                 new SegmentNodeStoreContainer(blob),
                 asList(),
-                DatastoreArguments.BlobMigrationCase.COPY_REFERENCES
-        });
-        params.add(new Object[]{
-                "Copy references, no blobstores defined, segment-tar -> segment-tar",
-                new SegmentTarNodeStoreContainer(blob),
-                new SegmentTarNodeStoreContainer(blob),
-                asList(),
-                DatastoreArguments.BlobMigrationCase.COPY_REFERENCES
+                Result.EXCEPTION
         });
         params.add(new Object[]{
-                "Copy references, no blobstores defined, document -> segment-tar",
-                new JdbcNodeStoreContainer(blob),
+                "Suppress the warning",
                 new SegmentNodeStoreContainer(blob),
-                asList("--src-user=sa", "--src-password=sa"),
-                DatastoreArguments.BlobMigrationCase.COPY_REFERENCES
-        });
-        params.add(new Object[]{
-                "Copy references, no blobstores defined, segment-tar -> document",
-                new SegmentTarNodeStoreContainer(blob),
-                new JdbcNodeStoreContainer(blob),
-                asList("--user=sa", "--password=sa"),
-                DatastoreArguments.BlobMigrationCase.UNSUPPORTED
-        });
-        params.add(new Object[]{
-                "Missing source, external destination",
-                new SegmentTarNodeStoreContainer(blob),
-                new SegmentTarNodeStoreContainer(blob),
-                asList("--datastore=" + blob.getDescription()),
-                DatastoreArguments.BlobMigrationCase.UNSUPPORTED
-        });
-        params.add(new Object[]{
-                "Copy embedded to embedded, no blobstores defined",
-                new SegmentTarNodeStoreContainer(),
-                new SegmentTarNodeStoreContainer(),
-                asList(),
-                DatastoreArguments.BlobMigrationCase.EMBEDDED_TO_EMBEDDED
-        });
-        params.add(new Object[]{
-                "Copy embedded to external, no blobstores defined",
-                new SegmentTarNodeStoreContainer(),
-                new SegmentTarNodeStoreContainer(blob),
-                asList("--datastore=" + blob.getDescription()),
-                DatastoreArguments.BlobMigrationCase.EMBEDDED_TO_EXTERNAL
+                new SegmentNodeStoreContainer(blob),
+                asList("--skip-checkpoints"),
+                Result.CHECKPOINTS_MISSING
         });
         params.add(new Object[]{
-                "Copy references, src blobstore defined",
+                "Source data store defined, checkpoints migrated",
                 new SegmentTarNodeStoreContainer(blob),
                 new SegmentTarNodeStoreContainer(blob),
                 asList("--src-datastore=" + blob.getDescription()),
-                DatastoreArguments.BlobMigrationCase.COPY_REFERENCES
-        });
-        params.add(new Object[]{
-                "Copy external to embedded, src blobstore defined",
-                new SegmentTarNodeStoreContainer(blob),
-                new SegmentTarNodeStoreContainer(),
-                asList("--copy-binaries", "--src-datastore=" + blob.getDescription()),
-                DatastoreArguments.BlobMigrationCase.EXTERNAL_TO_EMBEDDED
-        });
-        params.add(new Object[]{
-                "Copy external to external, src blobstore defined",
-                new SegmentTarNodeStoreContainer(blob),
-                new SegmentTarNodeStoreContainer(blob2),
-                asList("--copy-binaries", "--src-datastore=" + blob.getDescription(), "--datastore=" + blob2.getDescription()),
-                DatastoreArguments.BlobMigrationCase.EXTERNAL_TO_EXTERNAL
+                Result.CHECKPOINTS_COPIED
         });
         return params;
     }
@@ -139,13 +92,13 @@ public class CopyBinariesTest extends Ab
 
     private final List<String> args;
 
-    private final DatastoreArguments.BlobMigrationCase blobMigrationCase;
+    private final Result expectedResult;
 
-    public CopyBinariesTest(String name, NodeStoreContainer source, NodeStoreContainer destination, List<String> args, DatastoreArguments.BlobMigrationCase blobMigrationCase) throws IOException, CliArgumentException {
+    public CopyCheckpointsTest(String name, NodeStoreContainer source, NodeStoreContainer destination, List<String> args, Result expectedResult) throws IOException, CliArgumentException {
         this.source = source;
         this.destination = destination;
         this.args = args;
-        this.blobMigrationCase = blobMigrationCase;
+        this.expectedResult = expectedResult;
 
         this.source.clean();
         this.destination.clean();
@@ -186,24 +139,30 @@ public class CopyBinariesTest extends Ab
             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) {
+        } catch(RuntimeException e) {
+            if (expectedResult == Result.EXCEPTION) {
                 return;
             } else {
                 throw e;
             }
         }
+        if (expectedResult == Result.EXCEPTION) {
+            fail("Migration should fail");
+        }
         createSession();
     }
 
     @Test
     @Override
     public void validateMigration() throws RepositoryException, IOException, CliArgumentException {
-        if (blobMigrationCase == DatastoreArguments.BlobMigrationCase.UNSUPPORTED) {
-            return;
+        switch (expectedResult) {
+            case CHECKPOINTS_COPIED:
+                verifyCheckpoint();
+                break;
+
+            case CHECKPOINTS_MISSING:
+                verifyEmptyAsync();
+                break;
         }
-        verifyContent(session);
-        verifyBlob(session);
     }
 }
\ No newline at end of file

Modified: jackrabbit/oak/branches/1.6/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/AbstractOak2OakTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.6/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/AbstractOak2OakTest.java?rev=1786864&r1=1786863&r2=1786864&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.6/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/AbstractOak2OakTest.java (original)
+++ jackrabbit/oak/branches/1.6/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/AbstractOak2OakTest.java Tue Mar 14 09:38:37 2017
@@ -22,12 +22,14 @@ import static org.junit.Assert.assertEqu
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
+import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
+import java.util.Random;
 
 import javax.annotation.Nullable;
 import javax.jcr.Node;
@@ -41,7 +43,9 @@ import com.google.common.base.Function;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.jackrabbit.oak.api.Blob;
 import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.api.Type;
 import org.apache.jackrabbit.oak.commons.IOUtils;
 import org.apache.jackrabbit.oak.jcr.Jcr;
 import org.apache.jackrabbit.oak.jcr.repository.RepositoryImpl;
@@ -142,15 +146,24 @@ public abstract class AbstractOak2OakTes
         }
 
         NodeBuilder builder = target.getRoot().builder();
+        builder.setProperty("binary-prop", getRandomBlob(target));
         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.setProperty("binary-prop", getRandomBlob(target));
         builder.child(":async").setProperty("test", "123");
         target.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
     }
 
+    private Blob getRandomBlob(NodeStore target) throws IOException {
+        Random r = new Random();
+        byte[] buff = new byte[512 * 1024];
+        r.nextBytes(buff);
+        return target.createBlob(new ByteArrayInputStream(buff));
+    }
+
     @Test
     public void validateMigration() throws RepositoryException, IOException, CliArgumentException {
         verifyContent(session);
@@ -203,7 +216,7 @@ public abstract class AbstractOak2OakTes
         }
     }
 
-    private void verifyCheckpoint() {
+    protected void verifyCheckpoint() {
         assertEquals("after", destination.getRoot().getString("checkpoint-state"));
 
         Map<String, String> info = destination.checkpointInfo(checkpointReference);
@@ -237,7 +250,7 @@ public abstract class AbstractOak2OakTes
     }
 
     // OAK-2869
-    private void verifyEmptyAsync() {
+    protected void verifyEmptyAsync() {
         NodeState state = destination.getRoot().getChildNode(":async");
         assertFalse(state.hasProperty("test"));
     }

Modified: jackrabbit/oak/branches/1.6/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/CopyBinariesTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.6/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/CopyBinariesTest.java?rev=1786864&r1=1786863&r2=1786864&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.6/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/CopyBinariesTest.java (original)
+++ jackrabbit/oak/branches/1.6/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/CopyBinariesTest.java Tue Mar 14 09:38:37 2017
@@ -75,6 +75,13 @@ public class CopyBinariesTest extends Ab
                 DatastoreArguments.BlobMigrationCase.COPY_REFERENCES
         });
         params.add(new Object[]{
+                "Copy references, no blobstores defined, segment -> segment-tar",
+                new SegmentNodeStoreContainer(blob),
+                new SegmentTarNodeStoreContainer(blob),
+                asList(),
+                DatastoreArguments.BlobMigrationCase.COPY_REFERENCES
+        });
+        params.add(new Object[]{
                 "Copy references, no blobstores defined, document -> segment-tar",
                 new JdbcNodeStoreContainer(blob),
                 new SegmentNodeStoreContainer(blob),
@@ -164,7 +171,7 @@ public class CopyBinariesTest extends Ab
     @Override
     protected String[] getArgs() {
         List<String> result = new ArrayList<>(args);
-        result.addAll(asList("--disable-mmap", source.getDescription(), destination.getDescription()));
+        result.addAll(asList("--disable-mmap", "--skip-checkpoints", source.getDescription(), destination.getDescription()));
         return result.toArray(new String[result.size()]);
     }
 
@@ -203,7 +210,6 @@ public class CopyBinariesTest extends Ab
         if (blobMigrationCase == DatastoreArguments.BlobMigrationCase.UNSUPPORTED) {
             return;
         }
-        verifyContent(session);
-        verifyBlob(session);
+        super.validateMigration();
     }
 }
\ No newline at end of file

Modified: jackrabbit/oak/branches/1.6/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/SegmentNodeStoreContainer.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.6/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/SegmentNodeStoreContainer.java?rev=1786864&r1=1786863&r2=1786864&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.6/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/SegmentNodeStoreContainer.java (original)
+++ jackrabbit/oak/branches/1.6/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/SegmentNodeStoreContainer.java Tue Mar 14 09:38:37 2017
@@ -72,7 +72,10 @@ public class SegmentNodeStoreContainer i
 
     @Override
     public void close() {
-        fs.close();
+        if (fs != null) {
+            fs.close();
+            fs = null;
+        }
     }
 
     @Override