Added: 
jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/AssertingPeriodicReporter.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/AssertingPeriodicReporter.java?rev=1792993&view=auto
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/AssertingPeriodicReporter.java
 (added)
+++ 
jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/AssertingPeriodicReporter.java
 Fri Apr 28 07:16:13 2017
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.jackrabbit.oak.upgrade.nodestate.report;
+
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+
+import javax.annotation.Nonnull;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.hamcrest.CoreMatchers.allOf;
+import static org.hamcrest.CoreMatchers.any;
+import static org.hamcrest.CoreMatchers.anyOf;
+import static org.hamcrest.CoreMatchers.anything;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.collection.IsMapContaining.hasEntry;
+
+class AssertingPeriodicReporter extends PeriodicReporter {
+
+    private final Map<Long, String> reportedNodes = new HashMap<Long, 
String>();
+
+    private final Map<Long, String> reportedProperties = new HashMap<Long, 
String>();
+
+    public AssertingPeriodicReporter(final int nodeLogInterval, final int 
propertyLogInterval) {
+        super(nodeLogInterval, propertyLogInterval);
+    }
+
+    @Override
+    public void reset() {
+        super.reset();
+        reportedNodes.clear();
+        reportedProperties.clear();
+    }
+
+    @Override
+    protected void reportPeriodicNode(final long count, @Nonnull final 
ReportingNodeState nodeState) {
+        reportedNodes.put(count, nodeState.getPath());
+    }
+
+    @Override
+    protected void reportPeriodicProperty(final long count, @Nonnull final 
ReportingNodeState parent, @Nonnull final String propertyName) {
+        reportedProperties.put(count, PathUtils.concat(parent.getPath(), 
propertyName));
+    }
+
+    @Override
+    public String toString() {
+        return "Reported{ nodes: " + reportedNodes + " properties: " + 
reportedProperties + "}";
+    }
+
+    public static Matcher<AssertingPeriodicReporter> hasReportedNode(final int 
count, final String path) {
+        return hasReports(hasEntry((long) count, path), whatever());
+    }
+
+    public static Matcher<AssertingPeriodicReporter> hasReportedNode(final int 
count, final Matcher<String> pathMatcher) {
+        return hasReports(typesafeHasEntry(equalTo((long) count), 
pathMatcher), whatever());
+    }
+
+    public static Matcher<AssertingPeriodicReporter> hasReportedNodes(final 
String... paths) {
+        final List<Matcher<? super AssertingPeriodicReporter>> matchers =
+                new ArrayList<Matcher<? super AssertingPeriodicReporter>>();
+        for (final String path : paths) {
+            matchers.add(hasReports(typesafeHasEntry(any(Long.class), 
equalTo(path)), whatever()));
+        }
+        return allOf(matchers);
+    }
+
+    public static Matcher<AssertingPeriodicReporter> hasReportedProperty(final 
int count, final String path) {
+        return hasReports(whatever(), hasEntry((long) count, path));
+    }
+
+    public static Matcher<AssertingPeriodicReporter> hasReportedProperty(final 
int count, final Matcher<String> pathMatcher) {
+        return hasReports(whatever(), typesafeHasEntry(equalTo((long) count), 
pathMatcher));
+    }
+
+    public static Matcher<AssertingPeriodicReporter> hasReportedProperty(final 
String... paths) {
+        final List<Matcher<? super String>> pathMatchers = new 
ArrayList<Matcher<? super String>>();
+        for (final String path : paths) {
+            pathMatchers.add(equalTo(path));
+        }
+        return hasReports(whatever(), typesafeHasEntry(any(Long.class), 
allOf(pathMatchers)));
+    }
+
+    private static Matcher<Map<? extends Long, ? extends String>> whatever() {
+        return anyOf(typesafeHasEntry(any(Long.class), any(String.class)), 
anything());
+    }
+
+    private static Matcher<AssertingPeriodicReporter> hasReports(
+            final Matcher<Map<? extends Long, ? extends String>> 
nodeMapMatcher,
+            final Matcher<Map<? extends Long, ? extends String>> 
propertyMapMatcher) {
+
+        return new org.hamcrest.TypeSafeMatcher<AssertingPeriodicReporter>() {
+            @Override
+            protected boolean matchesSafely(final AssertingPeriodicReporter 
reporter) {
+                final boolean nodesMatch = 
nodeMapMatcher.matches(reporter.reportedNodes);
+                final boolean propertiesMatch = 
propertyMapMatcher.matches(reporter.reportedProperties);
+                return nodesMatch && propertiesMatch;
+            }
+
+            @Override
+            public void describeTo(final Description description) {
+                description
+                        .appendText("Reported{ nodes: ")
+                        .appendDescriptionOf(nodeMapMatcher)
+                        .appendText(", properties: ")
+                        .appendDescriptionOf(propertyMapMatcher);
+
+            }
+        };
+    }
+
+    // Java 6 fails to infer generics correctly if hasEntry is not wrapped in 
this
+    // method.
+    private static Matcher<Map<? extends Long, ? extends String>> 
typesafeHasEntry(
+            final Matcher<Long> countMatcher, final Matcher<String> 
pathMatcher) {
+        return hasEntry(countMatcher, pathMatcher);
+    }
+}

Added: 
jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/PeriodicReporterTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/PeriodicReporterTest.java?rev=1792993&view=auto
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/PeriodicReporterTest.java
 (added)
+++ 
jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/PeriodicReporterTest.java
 Fri Apr 28 07:16:13 2017
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.jackrabbit.oak.upgrade.nodestate.report;
+
+import org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.junit.Test;
+
+import static 
org.apache.jackrabbit.oak.upgrade.nodestate.report.AssertingPeriodicReporter.hasReportedNode;
+import static 
org.apache.jackrabbit.oak.upgrade.nodestate.report.AssertingPeriodicReporter.hasReportedProperty;
+import static org.junit.Assert.assertThat;
+
+public class PeriodicReporterTest {
+
+    @Test
+    public void callbackEveryTenNodes() {
+        final AssertingPeriodicReporter reporter = new 
AssertingPeriodicReporter(10, -1);
+        final NodeState counter = 
ReportingNodeState.wrap(EmptyNodeState.EMPTY_NODE, reporter)
+                .getChildNode("counter");
+
+        reporter.reset();
+        for (int i = 1; i < 40; i++) {
+            counter.getChildNode(Integer.toString(i));
+        }
+
+        assertThat(reporter, hasReportedNode(10, "/counter/10"));
+        assertThat(reporter, hasReportedNode(20, "/counter/20"));
+        assertThat(reporter, hasReportedNode(30, "/counter/30"));
+    }
+
+    @Test
+    public void callbackEveryTenProperties() {
+        final NodeBuilder builder = EmptyNodeState.EMPTY_NODE.builder();
+        for (int i = 1; i < 40; i++) {
+            builder.child("counter").setProperty(Integer.toString(i), i);
+        }
+
+        final AssertingPeriodicReporter reporter = new 
AssertingPeriodicReporter(-1, 10);
+        final NodeState counter = 
ReportingNodeState.wrap(builder.getNodeState(), reporter)
+                .getChildNode("counter");
+
+        reporter.reset();
+        for (int i = 1; i < 40; i++) {
+            counter.getProperty(Integer.toString(i));
+        }
+
+        assertThat(reporter, hasReportedProperty(10, "/counter/10"));
+        assertThat(reporter, hasReportedProperty(20, "/counter/20"));
+        assertThat(reporter, hasReportedProperty(30, "/counter/30"));
+    }
+
+}

Added: 
jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/ReportingNodeStateTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/ReportingNodeStateTest.java?rev=1792993&view=auto
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/ReportingNodeStateTest.java
 (added)
+++ 
jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/ReportingNodeStateTest.java
 Fri Apr 28 07:16:13 2017
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.jackrabbit.oak.upgrade.nodestate.report;
+
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState;
+import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.upgrade.util.NodeStateTestUtils;
+import org.junit.Test;
+
+import static 
org.apache.jackrabbit.oak.upgrade.nodestate.report.AssertingPeriodicReporter.hasReportedNode;
+import static 
org.apache.jackrabbit.oak.upgrade.nodestate.report.AssertingPeriodicReporter.hasReportedNodes;
+import static 
org.apache.jackrabbit.oak.upgrade.nodestate.report.AssertingPeriodicReporter.hasReportedProperty;
+import static org.hamcrest.CoreMatchers.any;
+import static org.hamcrest.CoreMatchers.not;
+import static org.junit.Assert.assertThat;
+
+public class ReportingNodeStateTest {
+
+    @Test
+    public void getChildNodeReportsNode() {
+        final AssertingPeriodicReporter reporter = new 
AssertingPeriodicReporter(10, 10);
+        final NodeState nodeState = 
ReportingNodeState.wrap(EmptyNodeState.EMPTY_NODE, reporter);
+
+        reporter.reset();
+        for (int i = 1; i <= 20; i++) {
+            nodeState.getChildNode("a" + i);
+        }
+
+        assertThat(reporter, hasReportedNode(10, "/a10"));
+        assertThat(reporter, hasReportedNode(20, "/a20"));
+    }
+
+    @Test
+    public void getChildNodeEntriesReportsNode() {
+        final NodeBuilder builder = EmptyNodeState.EMPTY_NODE.builder();
+        for (int i = 1; i < 20; i++) {
+            builder.child("a" + i);
+        }
+
+        final AssertingPeriodicReporter reporter = new 
AssertingPeriodicReporter(10, 10);
+        final NodeState nodeState = 
ReportingNodeState.wrap(builder.getNodeState(), reporter);
+
+        reporter.reset();
+        int counter = 0;
+        String name = "<none>";
+        for (final ChildNodeEntry child : nodeState.getChildNodeEntries()) {
+            if (++counter == 10) {
+                name = child.getName();
+                break;
+            }
+        }
+
+        assertThat(reporter, hasReportedNode(10, "/" + name));
+    }
+
+    @Test
+    public void getPropertyReportsProperty() {
+        final NodeBuilder builder = EmptyNodeState.EMPTY_NODE.builder();
+        final String name = "meaningOfLife";
+        builder.setProperty(name, "42");
+
+        final AssertingPeriodicReporter reporter = new 
AssertingPeriodicReporter(1, 1);
+        final NodeState nodeState = 
ReportingNodeState.wrap(builder.getNodeState(), reporter);
+
+        reporter.reset();
+
+        // 7 accesses via 7 methods
+        nodeState.getProperty(name);
+        nodeState.getBoolean(name);
+        nodeState.getLong(name);
+        nodeState.getString(name);
+        nodeState.getStrings(name);
+        nodeState.getName(name);
+        nodeState.getNames(name);
+
+        assertThat(reporter, not(hasReportedProperty(0, "/meaningOfLife")));
+        assertThat(reporter, hasReportedProperty(1, "/meaningOfLife"));
+        assertThat(reporter, hasReportedProperty(2, "/meaningOfLife"));
+        assertThat(reporter, hasReportedProperty(3, "/meaningOfLife"));
+        assertThat(reporter, hasReportedProperty(4, "/meaningOfLife"));
+        assertThat(reporter, hasReportedProperty(5, "/meaningOfLife"));
+        assertThat(reporter, hasReportedProperty(6, "/meaningOfLife"));
+        assertThat(reporter, hasReportedProperty(7, "/meaningOfLife"));
+        assertThat(reporter, not(hasReportedProperty(8, "/meaningOfLife")));
+    }
+
+    @Test
+    public void getPropertiesReportsProperty() {
+        final NodeBuilder builder = EmptyNodeState.EMPTY_NODE.builder();
+        for (int i = 0; i < 20; i++) {
+            builder.setProperty("a" + i, "foo");
+        }
+
+        final AssertingPeriodicReporter reporter = new 
AssertingPeriodicReporter(10, 10);
+        final NodeState nodeState = 
ReportingNodeState.wrap(builder.getNodeState(), reporter);
+
+        reporter.reset();
+        int counter = 0;
+        for (final PropertyState property : nodeState.getProperties()) {
+            if (++counter == 10) {
+                break;
+            }
+        }
+
+        assertThat(reporter, hasReportedProperty(10, any(String.class)));
+    }
+
+    @Test
+    public void compareAgainstBaseState() {
+        final NodeBuilder root = EmptyNodeState.EMPTY_NODE.builder();
+        root.child("a").child("aa");
+
+        final NodeState before = root.getNodeState();
+
+        root.child("a").child("ab");
+        root.child("b");
+
+        final AssertingPeriodicReporter reporter = new 
AssertingPeriodicReporter(1, -1);
+        final NodeState after = ReportingNodeState.wrap(root.getNodeState(), 
reporter);
+
+        reporter.reset();
+        NodeStateTestUtils.expectDifference()
+                .childNodeAdded(
+                        "/a/ab",
+                        "/b"
+                )
+                .childNodeChanged(
+                        "/a"
+                )
+                .strict()
+                .verify(before, after);
+
+        assertThat(reporter, hasReportedNodes("/a", "/a/ab", "/b"));
+    }
+}

Added: 
jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/util/NodeStateTestUtils.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/util/NodeStateTestUtils.java?rev=1792993&view=auto
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/util/NodeStateTestUtils.java
 (added)
+++ 
jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/util/NodeStateTestUtils.java
 Fri Apr 28 07:16:13 2017
@@ -0,0 +1,224 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.jackrabbit.oak.upgrade.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeStore;
+import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
+import org.apache.jackrabbit.oak.spi.commit.DefaultValidator;
+import org.apache.jackrabbit.oak.spi.commit.EditorDiff;
+import org.apache.jackrabbit.oak.spi.commit.EmptyHook;
+import org.apache.jackrabbit.oak.spi.commit.Validator;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.spi.state.NodeStore;
+
+public class NodeStateTestUtils {
+
+    private NodeStateTestUtils() {
+        // no instances
+    }
+
+    public static NodeStore createNodeStoreWithContent(String... paths) throws 
CommitFailedException, IOException {
+        final SegmentNodeStore store = new SegmentNodeStore();
+        final NodeBuilder builder = store.getRoot().builder();
+        for (String path : paths) {
+            create(builder, path);
+        }
+        commit(store, builder);
+        return store;
+    }
+
+    public static void create(NodeBuilder rootBuilder, String path, 
PropertyState... properties) {
+        final NodeBuilder builder = createOrGetBuilder(rootBuilder, path);
+        for (PropertyState property : properties) {
+            builder.setProperty(property);
+        }
+    }
+
+    public static void commit(NodeStore store, NodeBuilder rootBuilder) throws 
CommitFailedException {
+        store.merge(rootBuilder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
+    }
+
+    public static NodeState getNodeState(NodeState state, String path) {
+        NodeState current = state;
+        for (final String name : PathUtils.elements(path)) {
+            current = current.getChildNode(name);
+        }
+        return current;
+    }
+
+    public static NodeBuilder createOrGetBuilder(NodeBuilder builder, String 
path) {
+        NodeBuilder current = builder;
+        for (final String name : PathUtils.elements(path)) {
+            current = current.child(name);
+        }
+        return current;
+    }
+
+    public static void assertExists(NodeState state, String relPath) {
+        assertTrue(relPath + " should exist", getNodeState(state, 
relPath).exists());
+    }
+
+    public static void assertMissing(NodeState state, String relPath) {
+        assertFalse(relPath + " should not exist", getNodeState(state, 
relPath).exists());
+    }
+
+    public static ExpectedDifference expectDifference() {
+        return new ExpectedDifference();
+    }
+
+    public static class ExpectedDifference {
+
+        private ExpectedDifference() {
+        }
+
+        private final Map<String, Set<String>> expected = new HashMap<String, 
Set<String>>();
+
+        public void verify(NodeState before, NodeState after) {
+            final Map<String, Set<String>> actual = 
TestValidator.compare(before, after);
+            for (String type : expected.keySet()) {
+                if (!actual.containsKey(type)) {
+                    actual.put(type, Collections.<String>emptySet());
+                }
+                assertEquals(type, expected.get(type), actual.get(type));
+            }
+        }
+
+        public ExpectedDifference propertyAdded(String... paths) {
+            return expect("propertyAdded", paths);
+        }
+
+        public ExpectedDifference propertyChanged(String... paths) {
+            return expect("propertyChanged", paths);
+        }
+
+        public ExpectedDifference propertyDeleted(String... paths) {
+            return expect("propertyDeleted", paths);
+        }
+
+        public ExpectedDifference childNodeAdded(String... paths) {
+            return expect("childNodeAdded", paths);
+        }
+
+        public ExpectedDifference childNodeChanged(String... paths) {
+            return expect("childNodeChanged", paths);
+        }
+
+        public ExpectedDifference childNodeDeleted(String... paths) {
+            return expect("childNodeDeleted", paths);
+        }
+
+        public ExpectedDifference strict() {
+            return this.propertyAdded()
+                    .propertyChanged()
+                    .propertyDeleted()
+                    .childNodeAdded()
+                    .childNodeChanged()
+                    .childNodeDeleted();
+        }
+
+        private ExpectedDifference expect(String type, String... paths) {
+            if (!expected.containsKey(type)) {
+                expected.put(type, new TreeSet<String>());
+            }
+            Collections.addAll(expected.get(type), paths);
+            return this;
+        }
+    }
+
+    private static class TestValidator extends DefaultValidator {
+
+        final Map<String, Set<String>> actual = new HashMap<String, 
Set<String>>();
+
+        String path = "/";
+
+        public static Map<String, Set<String>> compare(NodeState before, 
NodeState after) {
+            final TestValidator validator = new TestValidator();
+            EditorDiff.process(validator, before, after);
+            return validator.actual;
+        }
+
+        @Override
+        public void leave(NodeState before, NodeState after) throws 
CommitFailedException {
+            path = PathUtils.getParentPath(path);
+        }
+
+        @Override
+        public void propertyAdded(PropertyState after) throws 
CommitFailedException {
+            record("propertyAdded", PathUtils.concat(path, after.getName()));
+        }
+
+        @Override
+        public void propertyChanged(PropertyState before, PropertyState after) 
throws CommitFailedException {
+            record("propertyChanged", PathUtils.concat(path, after.getName()));
+        }
+
+        @Override
+        public void propertyDeleted(PropertyState before) throws 
CommitFailedException {
+            record("propertyDeleted", PathUtils.concat(path, 
before.getName()));
+        }
+
+        @Override
+        public Validator childNodeAdded(String name, NodeState after) throws 
CommitFailedException {
+            path = PathUtils.concat(path, name);
+            record("childNodeAdded", path);
+            return this;
+        }
+
+        @Override
+        public Validator childNodeChanged(String name, NodeState before, 
NodeState after)
+                throws CommitFailedException {
+            // make sure not to record false positives (inefficient for large 
trees)
+            if (!before.equals(after)) {
+                path = PathUtils.concat(path, name);
+                record("childNodeChanged", path);
+                return this;
+            }
+            return null;
+        }
+
+        @Override
+        public Validator childNodeDeleted(String name, NodeState before) 
throws CommitFailedException {
+            path = PathUtils.concat(path, name);
+            record("childNodeDeleted", path);
+            return this;
+        }
+
+        private void record(String type, String path) {
+            if (!actual.containsKey(type)) {
+                actual.put(type, new TreeSet<String>());
+            }
+            actual.get(type).add(path);
+        }
+    }
+}

Added: 
jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/util/VersionCopyTestUtils.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/util/VersionCopyTestUtils.java?rev=1792993&view=auto
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/util/VersionCopyTestUtils.java
 (added)
+++ 
jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/util/VersionCopyTestUtils.java
 Fri Apr 28 07:16:13 2017
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.upgrade.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.version.Version;
+import javax.jcr.version.VersionHistory;
+import javax.jcr.version.VersionIterator;
+import javax.jcr.version.VersionManager;
+
+import com.google.common.collect.ImmutableList;
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.upgrade.version.VersionCopyConfiguration;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+public class VersionCopyTestUtils {
+
+    public static List<String> LABELS = ImmutableList.of("1.0", "1.1", "1.2");
+
+    public static Node getOrAddNode(Node parent, String relPath) throws 
RepositoryException {
+        Node currentParent = parent;
+        for (final String name : PathUtils.elements(relPath)) {
+            if (!currentParent.hasNode(name)) {
+                currentParent.addNode(name, JcrConstants.NT_UNSTRUCTURED);
+            }
+            currentParent = currentParent.getNode(name);
+        }
+        return currentParent;
+    }
+
+    public static Node getOrAddNodeWithMixins(Node parent, String name, String 
mixinType)
+            throws RepositoryException {
+        final Node node = getOrAddNode(parent, name);
+        node.addMixin(mixinType);
+        return node;
+    }
+
+    public static String createLabeledVersions(Node node)
+            throws RepositoryException, InterruptedException {
+        final Session session = node.getSession();
+        final VersionManager versionManager = 
session.getWorkspace().getVersionManager();
+        node.setProperty("version", "root");
+        session.save();
+
+        final String path = node.getPath();
+        final List<String> versionNames = new ArrayList<String>();
+        for (final String label : LABELS) {
+            node.setProperty("version", label);
+            session.save();
+            final Version v = versionManager.checkpoint(path);
+            versionNames.add(v.getName());
+        }
+
+        final VersionHistory history = versionManager.getVersionHistory(path);
+        for (final String versionName : versionNames) {
+            history.addVersionLabel(versionName, String.format("version %s", 
versionName), false);
+        }
+        return history.getPath();
+    }
+
+    public static void assertLabeledVersions(VersionHistory history) throws 
RepositoryException {
+        final VersionIterator versions = history.getAllVersions();
+        
assertFalse(versions.nextVersion().getFrozenNode().hasProperty("version")); // 
root
+        for (final String label : LABELS) {
+            assertEquals(label, 
versions.nextVersion().getFrozenNode().getProperty("version").getString());
+        }
+    }
+
+    public interface VersionCopySetup {
+        void setup(VersionCopyConfiguration config);
+    }
+}

Added: jackrabbit/oak/branches/1.0/oak-upgrade/src/test/resources/jcr2.zip
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/test/resources/jcr2.zip?rev=1792993&view=auto
==============================================================================
Binary files 
jackrabbit/oak/branches/1.0/oak-upgrade/src/test/resources/jcr2.zip (added) and 
jackrabbit/oak/branches/1.0/oak-upgrade/src/test/resources/jcr2.zip Fri Apr 28 
07:16:13 2017 differ

Modified: 
jackrabbit/oak/branches/1.0/oak-upgrade/src/test/resources/logback-test.xml
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/test/resources/logback-test.xml?rev=1792993&r1=1792992&r2=1792993&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-upgrade/src/test/resources/logback-test.xml 
(original)
+++ jackrabbit/oak/branches/1.0/oak-upgrade/src/test/resources/logback-test.xml 
Fri Apr 28 07:16:13 2017
@@ -29,7 +29,7 @@
         </encoder>
     </appender>
 
-    <root level="DEBUG">
+    <root level="INFO">
         <!--
         <appender-ref ref="console"/>
         -->

Added: 
jackrabbit/oak/branches/1.0/oak-upgrade/src/test/resources/segmentstore.zip
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/test/resources/segmentstore.zip?rev=1792993&view=auto
==============================================================================
Binary files 
jackrabbit/oak/branches/1.0/oak-upgrade/src/test/resources/segmentstore.zip 
(added) and 
jackrabbit/oak/branches/1.0/oak-upgrade/src/test/resources/segmentstore.zip Fri 
Apr 28 07:16:13 2017 differ

Added: 
jackrabbit/oak/branches/1.0/oak-upgrade/src/test/resources/test-nodetypes.cnd
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/test/resources/test-nodetypes.cnd?rev=1792993&view=auto
==============================================================================
--- 
jackrabbit/oak/branches/1.0/oak-upgrade/src/test/resources/test-nodetypes.cnd 
(added)
+++ 
jackrabbit/oak/branches/1.0/oak-upgrade/src/test/resources/test-nodetypes.cnd 
Fri Apr 28 07:16:13 2017
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+<test = 'http://example.org/jcr/test/1.0'>
+
+[test:Folder]
+  - * (undefined) multiple
+  - * (undefined)
+  + * (nt:base) = test:Folder version

Added: 
jackrabbit/oak/branches/1.0/oak-upgrade/src/test/resources/test-repo-1.0.zip
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/test/resources/test-repo-1.0.zip?rev=1792993&view=auto
==============================================================================
Binary files 
jackrabbit/oak/branches/1.0/oak-upgrade/src/test/resources/test-repo-1.0.zip 
(added) and 
jackrabbit/oak/branches/1.0/oak-upgrade/src/test/resources/test-repo-1.0.zip 
Fri Apr 28 07:16:13 2017 differ


Reply via email to