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/02/25 09:04:39 UTC

svn commit: r1732256 [2/2] - in /jackrabbit/oak/trunk/oak-solr-core/src: main/java/org/apache/jackrabbit/oak/plugins/index/solr/configuration/nodestate/ main/java/org/apache/jackrabbit/oak/plugins/index/solr/osgi/ main/java/org/apache/jackrabbit/oak/pl...

Modified: jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndexTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndexTest.java?rev=1732256&r1=1732255&r2=1732256&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndexTest.java (original)
+++ jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndexTest.java Thu Feb 25 08:04:39 2016
@@ -16,16 +16,20 @@
  */
 package org.apache.jackrabbit.oak.plugins.index.solr.query;
 
+import javax.annotation.Nonnull;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
-
-import javax.annotation.Nonnull;
+import java.util.LinkedList;
+import java.util.List;
 
 import org.apache.jackrabbit.oak.api.Result;
+import org.apache.jackrabbit.oak.api.Type;
 import org.apache.jackrabbit.oak.plugins.index.solr.TestUtils;
 import org.apache.jackrabbit.oak.plugins.index.solr.configuration.DefaultSolrConfiguration;
 import org.apache.jackrabbit.oak.plugins.index.solr.configuration.OakSolrConfiguration;
+import org.apache.jackrabbit.oak.plugins.index.solr.configuration.OakSolrConfigurationProvider;
+import org.apache.jackrabbit.oak.plugins.index.solr.server.SolrServerProvider;
 import org.apache.jackrabbit.oak.query.QueryEngineSettings;
 import org.apache.jackrabbit.oak.query.ast.Operator;
 import org.apache.jackrabbit.oak.query.ast.SelectorImpl;
@@ -34,6 +38,8 @@ import org.apache.jackrabbit.oak.spi.que
 import org.apache.jackrabbit.oak.spi.query.Filter;
 import org.apache.jackrabbit.oak.spi.query.IndexRow;
 import org.apache.jackrabbit.oak.spi.query.PropertyValues;
+import org.apache.jackrabbit.oak.spi.query.QueryIndex;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.apache.solr.client.solrj.SolrServer;
 import org.apache.solr.client.solrj.response.QueryResponse;
@@ -41,430 +47,275 @@ import org.apache.solr.common.SolrDocume
 import org.apache.solr.common.SolrDocumentList;
 import org.apache.solr.common.SolrInputDocument;
 import org.apache.solr.common.params.SolrParams;
+import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
+import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.EMPTY_NODE;
+import static org.junit.Assert.*;
 import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 /**
- * Tests for {@link org.apache.jackrabbit.oak.plugins.index.solr.query.SolrQueryIndex}
+ * Tests for {@link SolrQueryIndex}
  */
 public class SolrQueryIndexTest {
 
+    private NodeState nodeState;
+
+    @Before
+    public void setUp() throws Exception {
+        NodeState root = EMPTY_NODE;
+        NodeBuilder builder = root.builder();
+        builder.child("oak:index").child("solr")
+                .setProperty(JCR_PRIMARYTYPE, "oak:QueryIndexDefinition")
+                .setProperty("type", "solr")
+                .child("server").setProperty("solrServerType", "embedded");
+        nodeState = builder.getNodeState();
+    }
+
     @Test
-    public void testDefaultCostWithNoRestrictions() throws Exception {
-        NodeState root = mock(NodeState.class);
+    public void testNoIndexPlanWithNoRestrictions() throws Exception {
+
         SelectorImpl selector = mock(SelectorImpl.class);
 
-        SolrServer solrServer = mock(SolrServer.class);
-        OakSolrConfiguration configuration = new DefaultSolrConfiguration();
-        SolrQueryIndex solrQueryIndex = new SolrQueryIndex("solr", solrServer, configuration);
+        SolrQueryIndex solrQueryIndex = new SolrQueryIndex(null, null, null);
 
         FilterImpl filter = new FilterImpl(selector, "", new QueryEngineSettings());
-        double cost = solrQueryIndex.getCost(filter, root);
-        assertEquals(Double.POSITIVE_INFINITY, cost, 0);
+        List<QueryIndex.OrderEntry> sortOrder = new LinkedList<QueryIndex.OrderEntry>();
+        List<QueryIndex.IndexPlan> plans = solrQueryIndex.getPlans(filter, sortOrder, nodeState);
+        assertEquals(0, plans.size());
     }
 
+
     @Test
-    public void testDefaultCostWithPathRestrictions() throws Exception {
-        NodeState root = mock(NodeState.class);
-        when(root.getNames(any(String.class))).thenReturn(Collections.<String>emptySet());
-        SelectorImpl selector = new SelectorImpl(root, "a");
+    public void testNoPlanWithPathRestrictions() throws Exception {
+        SelectorImpl selector = new SelectorImpl(nodeState, "a");
 
-        SolrServer solrServer = mock(SolrServer.class);
-        OakSolrConfiguration configuration = new DefaultSolrConfiguration();
-        SolrQueryIndex solrQueryIndex = new SolrQueryIndex("solr", solrServer, configuration);
+        SolrQueryIndex solrQueryIndex = new SolrQueryIndex(null, null, null);
 
         FilterImpl filter = new FilterImpl(selector, "select * from [nt:base] as a where isdescendantnode(a, '/test')", new QueryEngineSettings());
         filter.restrictPath("/test", Filter.PathRestriction.ALL_CHILDREN);
-        double cost = solrQueryIndex.getCost(filter, root);
-        assertEquals(Double.POSITIVE_INFINITY, cost, 0);
+        List<QueryIndex.OrderEntry> sortOrder = new LinkedList<QueryIndex.OrderEntry>();
+        List<QueryIndex.IndexPlan> plans = solrQueryIndex.getPlans(filter, sortOrder, nodeState);
+        assertEquals(0, plans.size());
     }
 
     @Test
-    public void testCostWithOnlyPathRestrictionsEnabled() throws Exception {
-        NodeState root = mock(NodeState.class);
-        when(root.getNames(any(String.class))).thenReturn(Collections.<String>emptySet());
-        SelectorImpl selector = new SelectorImpl(root, "a");
+    public void testNoPlanWithOnlyPathRestrictionsEnabled() throws Exception {
+        NodeBuilder builder = nodeState.builder();
+        builder.child("oak:index").child("solr").setProperty("pathRestrictions", true);
+        nodeState = builder.getNodeState();
 
-        SolrServer solrServer = mock(SolrServer.class);
-        OakSolrConfiguration configuration = new DefaultSolrConfiguration() {
-            @Override
-            public boolean useForPathRestrictions() {
-                return true;
-            }
-        };
-        SolrQueryIndex solrQueryIndex = new SolrQueryIndex("solr", solrServer, configuration);
+        SelectorImpl selector = new SelectorImpl(nodeState, "a");
+
+        SolrQueryIndex solrQueryIndex = new SolrQueryIndex(null, null, null);
 
         FilterImpl filter = new FilterImpl(selector, "select * from [nt:base] as a where isdescendantnode(a, '/test')", new QueryEngineSettings());
         filter.restrictPath("/test", Filter.PathRestriction.ALL_CHILDREN);
-        double cost = solrQueryIndex.getCost(filter, root);
-        assertEquals(Double.POSITIVE_INFINITY, cost, 0);
+        List<QueryIndex.OrderEntry> sortOrder = new LinkedList<QueryIndex.OrderEntry>();
+        List<QueryIndex.IndexPlan> plans = solrQueryIndex.getPlans(filter, sortOrder, nodeState);
+        assertEquals(0, plans.size());
     }
 
     @Test
-    public void testCostWithPropertyAndPathRestrictionsEnabled() throws Exception {
-        NodeState root = mock(NodeState.class);
-        when(root.getNames(any(String.class))).thenReturn(Collections.<String>emptySet());
-        SelectorImpl selector = new SelectorImpl(root, "a");
+    public void testPlanWithPropertyAndPathRestrictionsEnabled() throws Exception {
+        NodeBuilder builder = nodeState.builder();
+        builder.child("oak:index").child("solr")
+                .setProperty("pathRestrictions", true)
+                .setProperty("propertyRestrictions", true);
+        nodeState = builder.getNodeState();
 
-        SolrServer solrServer = mock(SolrServer.class);
-        OakSolrConfiguration configuration = new DefaultSolrConfiguration() {
-            @Override
-            public boolean useForPathRestrictions() {
-                return true;
-            }
+        SelectorImpl selector = new SelectorImpl(nodeState, "a");
 
-            @Override
-            public boolean useForPropertyRestrictions() {
-                return true;
-            }
-        };
-        SolrQueryIndex solrQueryIndex = new SolrQueryIndex("solr", solrServer, configuration);
+        SolrQueryIndex solrQueryIndex = new SolrQueryIndex(null, null, null);
 
         FilterImpl filter = new FilterImpl(selector, "select * from [nt:base] as a where isdescendantnode(a, '/test')", new QueryEngineSettings());
         filter.restrictPath("/test", Filter.PathRestriction.ALL_CHILDREN);
         filter.restrictProperty("foo", Operator.EQUAL, PropertyValues.newString("bar"));
-        double cost = solrQueryIndex.getCost(filter, root);
-        assertEquals(5, cost, 0);
+        List<QueryIndex.OrderEntry> sortOrder = new LinkedList<QueryIndex.OrderEntry>();
+        List<QueryIndex.IndexPlan> plans = solrQueryIndex.getPlans(filter, sortOrder, nodeState);
+        assertEquals(1, plans.size());
     }
 
     @Test
-    public void testDefaultCostWithPropertyRestrictions() throws Exception {
-        NodeState root = mock(NodeState.class);
-        when(root.getNames(any(String.class))).thenReturn(Collections.<String>emptySet());
-        SelectorImpl selector = new SelectorImpl(root, "a");
+    public void testNoPlanWithPropertyRestrictions() throws Exception {
+        SelectorImpl selector = new SelectorImpl(nodeState, "a");
 
-        SolrServer solrServer = mock(SolrServer.class);
-        OakSolrConfiguration configuration = new DefaultSolrConfiguration();
-        SolrQueryIndex solrQueryIndex = new SolrQueryIndex("solr", solrServer, configuration);
+        SolrQueryIndex solrQueryIndex = new SolrQueryIndex(null, null, null);
 
         FilterImpl filter = new FilterImpl(selector, "select * from [nt:base] as a where name = 'hello')", new QueryEngineSettings());
         filter.restrictProperty("name", Operator.EQUAL, PropertyValues.newString("hello"));
-        double cost = solrQueryIndex.getCost(filter, root);
-        assertEquals(Double.POSITIVE_INFINITY, cost, 0);
+        List<QueryIndex.OrderEntry> sortOrder = new LinkedList<QueryIndex.OrderEntry>();
+        List<QueryIndex.IndexPlan> plans = solrQueryIndex.getPlans(filter, sortOrder, nodeState);
+        assertEquals(0, plans.size());
     }
 
     @Test
-    public void testCostWithPropertyRestrictionsEnabled() throws Exception {
-        NodeState root = mock(NodeState.class);
-        when(root.getNames(any(String.class))).thenReturn(Collections.<String>emptySet());
-        SelectorImpl selector = new SelectorImpl(root, "a");
+    public void testPlanWithPropertyRestrictionsEnabled() throws Exception {
+        NodeBuilder builder = nodeState.builder();
+        builder.child("oak:index").child("solr")
+                .setProperty("propertyRestrictions", true);
+        nodeState = builder.getNodeState();
 
-        SolrServer solrServer = mock(SolrServer.class);
-        OakSolrConfiguration configuration = new DefaultSolrConfiguration() {
-            @Override
-            public boolean useForPropertyRestrictions() {
-                return true;
-            }
-        };
-        SolrQueryIndex solrQueryIndex = new SolrQueryIndex("solr", solrServer, configuration);
+        SelectorImpl selector = new SelectorImpl(nodeState, "a");
+
+        SolrQueryIndex solrQueryIndex = new SolrQueryIndex(null, null, null);
 
         FilterImpl filter = new FilterImpl(selector, "select * from [nt:base] as a where name = 'hello')", new QueryEngineSettings());
         filter.restrictProperty("name", Operator.EQUAL, PropertyValues.newString("hello"));
-        double cost = solrQueryIndex.getCost(filter, root);
-        assertEquals(10, cost, 0);
+        List<QueryIndex.OrderEntry> sortOrder = new LinkedList<QueryIndex.OrderEntry>();
+        List<QueryIndex.IndexPlan> plans = solrQueryIndex.getPlans(filter, sortOrder, nodeState);
+        assertEquals(1, plans.size());
     }
 
     @Test
-    public void testDefaultCostWithPrimaryTypeRestrictions() throws Exception {
-        NodeState root = mock(NodeState.class);
-        when(root.getNames(any(String.class))).thenReturn(Collections.<String>emptySet());
-        SelectorImpl selector = new SelectorImpl(root, "a");
+    public void testNoPlanWithPrimaryTypeRestrictions() throws Exception {
+        SelectorImpl selector = new SelectorImpl(nodeState, "a");
 
-        SolrServer solrServer = mock(SolrServer.class);
-        OakSolrConfiguration configuration = new DefaultSolrConfiguration();
-        SolrQueryIndex solrQueryIndex = new SolrQueryIndex("solr", solrServer, configuration);
+        SolrQueryIndex solrQueryIndex = new SolrQueryIndex(null, null, null);
 
         FilterImpl filter = new FilterImpl(selector, "select * from [nt:base] as a where jcr:primaryType = 'nt:unstructured')", new QueryEngineSettings());
         filter.restrictProperty("jcr:primaryType", Operator.EQUAL, PropertyValues.newString("nt:unstructured"));
-        double cost = solrQueryIndex.getCost(filter, root);
-        assertEquals(Double.POSITIVE_INFINITY, cost, 0);
+        List<QueryIndex.OrderEntry> sortOrder = new LinkedList<QueryIndex.OrderEntry>();
+        List<QueryIndex.IndexPlan> plans = solrQueryIndex.getPlans(filter, sortOrder, nodeState);
+        assertEquals(0, plans.size());
     }
 
     @Test
-    public void testCostWithOnlyPrimaryTypeRestrictionsEnabled() throws Exception {
-        NodeState root = mock(NodeState.class);
-        when(root.getNames(any(String.class))).thenReturn(Collections.<String>emptySet());
-        SelectorImpl selector = new SelectorImpl(root, "a");
+    public void testNoPlanWithOnlyPrimaryTypeRestrictionsEnabled() throws Exception {
+        NodeBuilder builder = nodeState.builder();
+        builder.child("oak:index").child("solr").setProperty("primaryTypes", true);
+        nodeState = builder.getNodeState();
 
-        SolrServer solrServer = mock(SolrServer.class);
-        OakSolrConfiguration configuration = new DefaultSolrConfiguration() {
-            @Override
-            public boolean useForPrimaryTypes() {
-                return true;
-            }
-        };
-        SolrQueryIndex solrQueryIndex = new SolrQueryIndex("solr", solrServer, configuration);
+        SelectorImpl selector = new SelectorImpl(nodeState, "a");
+
+        SolrQueryIndex solrQueryIndex = new SolrQueryIndex(null, null, null);
 
         FilterImpl filter = new FilterImpl(selector, "select * from [nt:base] as a where jcr:primaryType = 'nt:unstructured')", new QueryEngineSettings());
         filter.restrictProperty("jcr:primaryType", Operator.EQUAL, PropertyValues.newString("nt:unstructured"));
-        double cost = solrQueryIndex.getCost(filter, root);
-        assertEquals(Double.POSITIVE_INFINITY, cost, 0);
+        List<QueryIndex.OrderEntry> sortOrder = new LinkedList<QueryIndex.OrderEntry>();
+        List<QueryIndex.IndexPlan> plans = solrQueryIndex.getPlans(filter, sortOrder, nodeState);
+        assertEquals(0, plans.size());
     }
 
     @Test
-    public void testCostWithPropertyAndPrimaryTypeRestrictionsEnabled() throws Exception {
-        NodeState root = mock(NodeState.class);
-        when(root.getNames(any(String.class))).thenReturn(Collections.<String>emptySet());
-        SelectorImpl selector = new SelectorImpl(root, "a");
+    public void testPlanWithPropertyAndPrimaryTypeRestrictionsEnabled() throws Exception {
+        NodeBuilder builder = nodeState.builder();
+        builder.child("oak:index").child("solr")
+                .setProperty("propertyRestrictions", true)
+                .setProperty("primaryTypes", true);
+        nodeState = builder.getNodeState();
 
-        SolrServer solrServer = mock(SolrServer.class);
-        OakSolrConfiguration configuration = new DefaultSolrConfiguration() {
-            @Override
-            public boolean useForPrimaryTypes() {
-                return true;
-            }
+        SelectorImpl selector = new SelectorImpl(nodeState, "a");
 
-            @Override
-            public boolean useForPropertyRestrictions() {
-                return true;
-            }
-        };
-        SolrQueryIndex solrQueryIndex = new SolrQueryIndex("solr", solrServer, configuration);
+        SolrQueryIndex solrQueryIndex = new SolrQueryIndex(null, null, null);
 
         FilterImpl filter = new FilterImpl(selector, "select * from [nt:base] as a where jcr:primaryType = 'nt:unstructured')", new QueryEngineSettings());
         filter.restrictProperty("jcr:primaryType", Operator.EQUAL, PropertyValues.newString("nt:unstructured"));
         filter.restrictProperty("name", Operator.EQUAL, PropertyValues.newString("hello"));
-        double cost = solrQueryIndex.getCost(filter, root);
-        assertEquals(5, cost, 0);
+        List<QueryIndex.OrderEntry> sortOrder = new LinkedList<QueryIndex.OrderEntry>();
+        List<QueryIndex.IndexPlan> plans = solrQueryIndex.getPlans(filter, sortOrder, nodeState);
+        assertEquals(1, plans.size());
     }
 
     @Test
-    public void testCostWithPropertyRestrictionsEnabledButPropertyIgnored() throws Exception {
-        NodeState root = mock(NodeState.class);
-        when(root.getNames(any(String.class))).thenReturn(Collections.<String>emptySet());
-        SelectorImpl selector = new SelectorImpl(root, "a");
+    public void testNoPlanWithPropertyRestrictionsEnabledButPropertyIgnored() throws Exception {
+        NodeBuilder builder = nodeState.builder();
+        builder.child("oak:index").child("solr")
+                .setProperty("ignoredProperties", Collections.singleton("name"), Type.STRINGS)
+                .setProperty("propertyRestrictions", true);
+        nodeState = builder.getNodeState();
 
-        SolrServer solrServer = mock(SolrServer.class);
-        OakSolrConfiguration configuration = new DefaultSolrConfiguration() {
-            @Override
-            public boolean useForPropertyRestrictions() {
-                return true;
-            }
+        SelectorImpl selector = new SelectorImpl(nodeState, "a");
 
-            @Nonnull
-            @Override
-            public Collection<String> getIgnoredProperties() {
-                return Arrays.asList("name");
-            }
-        };
-        SolrQueryIndex solrQueryIndex = new SolrQueryIndex("solr", solrServer, configuration);
+        SolrQueryIndex solrQueryIndex = new SolrQueryIndex(null, null, null);
 
         FilterImpl filter = new FilterImpl(selector, "select * from [nt:base] as a where name = 'hello')", new QueryEngineSettings());
         filter.restrictProperty("name", Operator.EQUAL, PropertyValues.newString("hello"));
-        double cost = solrQueryIndex.getCost(filter, root);
-        assertEquals(Double.POSITIVE_INFINITY, cost, 0);
+        List<QueryIndex.OrderEntry> sortOrder = new LinkedList<QueryIndex.OrderEntry>();
+        List<QueryIndex.IndexPlan> plans = solrQueryIndex.getPlans(filter, sortOrder, nodeState);
+        assertEquals(0, plans.size()); // there's no plan matching the filter
     }
 
     @Test
-    public void testCostWithPropertyRestrictionsEnabledButNotUsedProperty() throws Exception {
-        NodeState root = mock(NodeState.class);
-        when(root.getNames(any(String.class))).thenReturn(Collections.<String>emptySet());
-        SelectorImpl selector = new SelectorImpl(root, "a");
+    public void testNoPlanWithPropertyRestrictionsEnabledButNotUsedProperty() throws Exception {
+        NodeBuilder builder = nodeState.builder();
+        builder.child("oak:index").child("solr")
+                .setProperty("usedProperties", Collections.singleton("foo"), Type.STRINGS)
+                .setProperty("propertyRestrictions", true);
+        nodeState = builder.getNodeState();
 
-        SolrServer solrServer = mock(SolrServer.class);
-        OakSolrConfiguration configuration = new DefaultSolrConfiguration() {
-            @Override
-            public boolean useForPropertyRestrictions() {
-                return true;
-            }
+        SelectorImpl selector = new SelectorImpl(nodeState, "a");
 
-            @Nonnull
-            @Override
-            public Collection<String> getUsedProperties() {
-                return Arrays.asList("foo");
-            }
-        };
-        SolrQueryIndex solrQueryIndex = new SolrQueryIndex("solr", solrServer, configuration);
+        SolrQueryIndex solrQueryIndex = new SolrQueryIndex(null, null, null);
 
         FilterImpl filter = new FilterImpl(selector, "select * from [nt:base] as a where name = 'hello')", new QueryEngineSettings());
         filter.restrictProperty("name", Operator.EQUAL, PropertyValues.newString("hello"));
-        double cost = solrQueryIndex.getCost(filter, root);
-        assertEquals(Double.POSITIVE_INFINITY, cost, 0);
+        List<QueryIndex.OrderEntry> sortOrder = new LinkedList<QueryIndex.OrderEntry>();
+        List<QueryIndex.IndexPlan> plans = solrQueryIndex.getPlans(filter, sortOrder, nodeState);
+        assertEquals(0, plans.size());
     }
 
     @Test
-    public void testCostWithPropertyRestrictionsEnabledAndUsedProperty() throws Exception {
-        NodeState root = mock(NodeState.class);
-        when(root.getNames(any(String.class))).thenReturn(Collections.<String>emptySet());
-        SelectorImpl selector = new SelectorImpl(root, "a");
-
-        SolrServer solrServer = mock(SolrServer.class);
-        OakSolrConfiguration configuration = new DefaultSolrConfiguration() {
-            @Override
-            public boolean useForPropertyRestrictions() {
-                return true;
-            }
-
-            @Nonnull
-            @Override
-            public Collection<String> getUsedProperties() {
-                return Arrays.asList("name");
-            }
-        };
-        SolrQueryIndex solrQueryIndex = new SolrQueryIndex("solr", solrServer, configuration);
-
-        FilterImpl filter = new FilterImpl(selector, "select * from [nt:base] as a where name = 'hello')", new QueryEngineSettings());
-        filter.restrictProperty("name", Operator.EQUAL, PropertyValues.newString("hello"));
-        double cost = solrQueryIndex.getCost(filter, root);
-        assertEquals(10, cost, 0);
-    }
-
-    @Test
-    public void testQueryOnIgnoredExistingProperty() throws Exception {
-        NodeState root = mock(NodeState.class);
-        when(root.getNames(any(String.class))).thenReturn(Collections.<String>emptySet());
-        SelectorImpl selector = new SelectorImpl(root, "a");
+    public void testPlanWithPropertyRestrictionsEnabledAndUsedProperty() throws Exception {
+        NodeBuilder builder = nodeState.builder();
+        builder.child("oak:index").child("solr")
+                .setProperty("usedProperties", Collections.singleton("name"), Type.STRINGS)
+                .setProperty("propertyRestrictions", true);
+        nodeState = builder.getNodeState();
 
-        SolrServer solrServer = TestUtils.createSolrServer();
-        SolrInputDocument document = new SolrInputDocument();
-        document.addField("path_exact", "/a/b");
-        document.addField("name", "hello");
-        solrServer.add(document);
-        solrServer.commit();
-        OakSolrConfiguration configuration = new DefaultSolrConfiguration() {
-            @Override
-            public boolean useForPropertyRestrictions() {
-                return true;
-            }
+        SelectorImpl selector = new SelectorImpl(nodeState, "a");
 
-            @Nonnull
-            @Override
-            public Collection<String> getIgnoredProperties() {
-                return Arrays.asList("name");
-            }
-        };
-        SolrQueryIndex solrQueryIndex = new SolrQueryIndex("solr", solrServer, configuration);
+        SolrQueryIndex solrQueryIndex = new SolrQueryIndex(null, null, null);
 
         FilterImpl filter = new FilterImpl(selector, "select * from [nt:base] as a where name = 'hello')", new QueryEngineSettings());
         filter.restrictProperty("name", Operator.EQUAL, PropertyValues.newString("hello"));
-        String plan = solrQueryIndex.getPlan(filter, root);
-        assertNotNull(plan);
-        assertTrue(plan.contains("q=*%3A*")); // querying on property name is not possible, then falling back to a match all query
+        List<QueryIndex.OrderEntry> sortOrder = new LinkedList<QueryIndex.OrderEntry>();
+        List<QueryIndex.IndexPlan> plans = solrQueryIndex.getPlans(filter, sortOrder, nodeState);
+        assertEquals(1, plans.size());
     }
 
     @Test
-    public void testQueryOnExplicitlyUsedProperty() throws Exception {
-        NodeState root = mock(NodeState.class);
-        when(root.getNames(any(String.class))).thenReturn(Collections.<String>emptySet());
-        SelectorImpl selector = new SelectorImpl(root, "a");
+    public void testNoPlanWithPropertyNotListedInUsedProperties() throws Exception {
+        NodeBuilder builder = nodeState.builder();
+        builder.child("oak:index").child("solr")
+                .setProperty("usedProperties", Collections.singleton("name"), Type.STRINGS)
+                .setProperty("propertyRestrictions", true);
+        nodeState = builder.getNodeState();
 
-        SolrServer solrServer = TestUtils.createSolrServer();
-        SolrInputDocument document = new SolrInputDocument();
-        document.addField("path_exact", "/a/b");
-        document.addField("name", "hello");
-        solrServer.add(document);
-        solrServer.commit();
-        OakSolrConfiguration configuration = new DefaultSolrConfiguration() {
-            @Override
-            public boolean useForPropertyRestrictions() {
-                return true;
-            }
+        SelectorImpl selector = new SelectorImpl(nodeState, "a");
 
-            @Nonnull
-            @Override
-            public Collection<String> getUsedProperties() {
-                return Arrays.asList("name");
-            }
-        };
-        SolrQueryIndex solrQueryIndex = new SolrQueryIndex("solr", solrServer, configuration);
-
-        FilterImpl filter = new FilterImpl(selector, "select * from [nt:base] as a where name = 'hello')", new QueryEngineSettings());
-        filter.restrictProperty("name", Operator.EQUAL, PropertyValues.newString("hello"));
-        String plan = solrQueryIndex.getPlan(filter, root);
-        assertNotNull(plan);
-        assertTrue(plan.contains("name%3Ahello")); // querying on property name is possible
-    }
-
-    @Test
-    public void testQueryOnPropertyNotListedInUsedProperties() throws Exception {
-        NodeState root = mock(NodeState.class);
-        when(root.getNames(any(String.class))).thenReturn(Collections.<String>emptySet());
-        SelectorImpl selector = new SelectorImpl(root, "a");
-
-        SolrServer solrServer = TestUtils.createSolrServer();
-        SolrInputDocument document = new SolrInputDocument();
-        document.addField("path_exact", "/a/b");
-        document.addField("name", "hello");
-        solrServer.add(document);
-        solrServer.commit();
-        OakSolrConfiguration configuration = new DefaultSolrConfiguration() {
-            @Override
-            public boolean useForPropertyRestrictions() {
-                return true;
-            }
-
-            @Nonnull
-            @Override
-            public Collection<String> getUsedProperties() {
-                return Arrays.asList("name");
-            }
-        };
-        SolrQueryIndex solrQueryIndex = new SolrQueryIndex("solr", solrServer, configuration);
+        SolrQueryIndex solrQueryIndex = new SolrQueryIndex(null, null, null);
 
         FilterImpl filter = new FilterImpl(selector, "select * from [nt:base] as a where foo = 'bar')", new QueryEngineSettings());
         filter.restrictProperty("foo", Operator.EQUAL, PropertyValues.newString("bar"));
-        String plan = solrQueryIndex.getPlan(filter, root);
-        assertNotNull(plan);
-        assertTrue(plan.contains("*%3A*")); // querying on property foo is not possible, as the only usable property is 'name'
+        List<QueryIndex.OrderEntry> sortOrder = new LinkedList<QueryIndex.OrderEntry>();
+        List<QueryIndex.IndexPlan> plans = solrQueryIndex.getPlans(filter, sortOrder, nodeState);
+        assertEquals(0, plans.size());
     }
 
-    @Test
-    public void testQueryOnExistingProperty() throws Exception {
-        NodeState root = mock(NodeState.class);
-        when(root.getNames(any(String.class))).thenReturn(Collections.<String>emptySet());
-        SelectorImpl selector = new SelectorImpl(root, "a");
-
-        SolrServer solrServer = TestUtils.createSolrServer();
-        SolrInputDocument document = new SolrInputDocument();
-        document.addField("path_exact", "/a/b");
-        document.addField("name", "hello");
-        solrServer.add(document);
-        solrServer.commit();
-        OakSolrConfiguration configuration = new DefaultSolrConfiguration() {
-            @Override
-            public boolean useForPropertyRestrictions() {
-                return true;
-            }
-        };
-        SolrQueryIndex solrQueryIndex = new SolrQueryIndex("solr", solrServer, configuration);
+   @Test
+    public void testUnion() throws Exception {
+       SelectorImpl selector = mock(SelectorImpl.class);
 
-        FilterImpl filter = new FilterImpl(selector, "select * from [nt:base] as a where name = 'hello')", new QueryEngineSettings());
-        filter.restrictProperty("name", Operator.EQUAL, PropertyValues.newString("hello"));
-        String plan = solrQueryIndex.getPlan(filter, root);
-        assertNotNull(plan);
-        assertTrue(plan.contains("q=name%3Ahello")); // query gets converted to a fielded query on name field
-    }
+       SolrQueryIndex solrQueryIndex = new SolrQueryIndex(null, null, null);
 
-    @Test
-    public void testUnion() throws Exception {
-        NodeState root = mock(NodeState.class);
-        when(root.getNames(any(String.class))).thenReturn(Collections.<String>emptySet());
-        SelectorImpl selector = new SelectorImpl(root, "a");
-        String sqlQuery = "select [jcr:path], [jcr:score], [rep:excerpt] from [nt:hierarchyNode] as a where" +
+       String sqlQuery = "select [jcr:path], [jcr:score], [rep:excerpt] from [nt:hierarchyNode] as a where" +
                 " isdescendantnode(a, '/content') and contains([jcr:content/*], 'founded') union select [jcr:path]," +
                 " [jcr:score], [rep:excerpt] from [nt:hierarchyNode] as a where isdescendantnode(a, '/content') and " +
                 "contains([jcr:content/jcr:title], 'founded') union select [jcr:path], [jcr:score], [rep:excerpt]" +
                 " from [nt:hierarchyNode] as a where isdescendantnode(a, '/content') and " +
                 "contains([jcr:content/jcr:description], 'founded') order by [jcr:score] desc";
-        SolrServer solrServer = TestUtils.createSolrServer();
-        OakSolrConfiguration configuration = new DefaultSolrConfiguration() {
-            @Override
-            public boolean useForPropertyRestrictions() {
-                return true;
-            }
-        };
-        SolrQueryIndex solrQueryIndex = new SolrQueryIndex("solr", solrServer, configuration);
         FilterImpl filter = new FilterImpl(selector, sqlQuery, new QueryEngineSettings());
-        Cursor cursor = solrQueryIndex.query(filter, root);
-        assertNotNull(cursor);
+       List<QueryIndex.OrderEntry> sortOrder = new LinkedList<QueryIndex.OrderEntry>();
+       List<QueryIndex.IndexPlan> plans = solrQueryIndex.getPlans(filter, sortOrder, nodeState);
+       assertEquals(0, plans.size());
     }
 
+    @Ignore
     @Test
     public void testSize() throws Exception {
         NodeState root = mock(NodeState.class);
@@ -473,13 +324,17 @@ public class SolrQueryIndexTest {
         String sqlQuery = "select [jcr:path], [jcr:score] from [nt:base] as a where" +
                 " contains([jcr:content/*], 'founded')";
         SolrServer solrServer = TestUtils.createSolrServer();
+        SolrServerProvider solrServerProvider = mock(SolrServerProvider.class);
+        OakSolrConfigurationProvider configurationProvider = mock(OakSolrConfigurationProvider.class);
         OakSolrConfiguration configuration = new DefaultSolrConfiguration() {
             @Override
             public boolean useForPropertyRestrictions() {
                 return true;
             }
         };
-        SolrQueryIndex solrQueryIndex = new SolrQueryIndex("solr", solrServer, configuration);
+        when(configurationProvider.getConfiguration()).thenReturn(configuration);
+
+        SolrQueryIndex solrQueryIndex = new SolrQueryIndex(null, configurationProvider, solrServerProvider);
         FilterImpl filter = new FilterImpl(selector, sqlQuery, new QueryEngineSettings());
         Cursor cursor = solrQueryIndex.query(filter, root);
         assertNotNull(cursor);
@@ -490,6 +345,7 @@ public class SolrQueryIndexTest {
         assertTrue(Math.abs(sizeExact - sizeFastApprox) > 10000);
     }
 
+    @Ignore
     @Test
     public void testNoMoreThanThreeSolrRequests() throws Exception {
         NodeState root = mock(NodeState.class);
@@ -498,6 +354,9 @@ public class SolrQueryIndexTest {
         String sqlQuery = "select [jcr:path], [jcr:score] from [nt:base] as a where" +
                 " contains([jcr:content/*], 'founded')";
         SolrServer solrServer = mock(SolrServer.class);
+        SolrServerProvider solrServerProvider = mock(SolrServerProvider.class);
+        when(solrServerProvider.getSearchingSolrServer()).thenReturn(solrServer);
+        OakSolrConfigurationProvider configurationProvider = mock(OakSolrConfigurationProvider.class);
         OakSolrConfiguration configuration = new DefaultSolrConfiguration() {
             @Override
             public boolean useForPropertyRestrictions() {
@@ -509,7 +368,9 @@ public class SolrQueryIndexTest {
                 return 10;
             }
         };
-        SolrQueryIndex solrQueryIndex = new SolrQueryIndex("solr", solrServer, configuration);
+        when(configurationProvider.getConfiguration()).thenReturn(configuration);
+
+        SolrQueryIndex solrQueryIndex = new SolrQueryIndex(null, configurationProvider, solrServerProvider);
         FilterImpl filter = new FilterImpl(selector, sqlQuery, new QueryEngineSettings());
         CountingResponse response = new CountingResponse(0);
         when(solrServer.query(any(SolrParams.class))).thenReturn(response);

Added: jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SubtreeSolrIndexIT.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SubtreeSolrIndexIT.java?rev=1732256&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SubtreeSolrIndexIT.java (added)
+++ jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SubtreeSolrIndexIT.java Thu Feb 25 08:04:39 2016
@@ -0,0 +1,104 @@
+/*
+ * 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.plugins.index.solr.query;
+
+import javax.jcr.query.Query;
+import java.util.Iterator;
+
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.jackrabbit.oak.Oak;
+import org.apache.jackrabbit.oak.api.ContentRepository;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.plugins.index.solr.configuration.DefaultSolrConfigurationProvider;
+import org.apache.jackrabbit.oak.plugins.index.solr.index.SolrIndexEditorProvider;
+import org.apache.jackrabbit.oak.plugins.index.solr.server.DefaultSolrServerProvider;
+import org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent;
+import org.apache.jackrabbit.oak.query.AbstractQueryTest;
+import org.apache.jackrabbit.oak.spi.security.OpenSecurityProvider;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestName;
+
+import static org.junit.Assert.*;
+
+/**
+ * Integration test for indexing / search over subtrees with Solr index.
+ */
+public class SubtreeSolrIndexIT extends AbstractQueryTest {
+
+    public static final String SUBTREE = "subtree";
+
+    @Rule
+    public TestName name = new TestName();
+
+    @Override
+    protected void createTestIndexNode() throws Exception {
+        Tree rootTree = root.getTree("/");
+        Tree subtree = rootTree.addChild(SUBTREE);
+        Tree solrIndexNode = createTestIndexNode(subtree, SolrQueryIndex.TYPE);
+        solrIndexNode.setProperty("pathRestrictions", false);
+        solrIndexNode.setProperty("propertyRestrictions", true);
+        solrIndexNode.setProperty("primaryTypes", false);
+        solrIndexNode.setProperty("commitPolicy", "hard");
+        Tree server = solrIndexNode.addChild("server");
+        server.setProperty("solrServerType", "embedded");
+        server.setProperty("solrHomePath", "target/" + name.getMethodName());
+
+        root.commit();
+    }
+
+    @Override
+    protected ContentRepository createRepository() {
+        try {
+            DefaultSolrServerProvider solrServerProvider = new DefaultSolrServerProvider();
+            DefaultSolrConfigurationProvider oakSolrConfigurationProvider = new DefaultSolrConfigurationProvider();
+            return new Oak().with(new InitialContent())
+                    .with(new OpenSecurityProvider())
+                    .with(new SolrQueryIndexProvider(solrServerProvider, oakSolrConfigurationProvider))
+                    .with(new SolrIndexEditorProvider(solrServerProvider, oakSolrConfigurationProvider))
+                    .createContentRepository();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Test
+    public void test() throws Exception {
+
+        Tree content = root.getTree("/").getChild(SUBTREE);
+        Tree a = content.addChild("a");
+        a.setProperty(JcrConstants.JCR_PRIMARYTYPE, JcrConstants.NT_UNSTRUCTURED, Type.NAME);
+        a.setProperty("foo", "doc bye");
+        a.setProperty("loc", "2");
+        Tree b = content.addChild("b");
+        b.setProperty(JcrConstants.JCR_PRIMARYTYPE, JcrConstants.NT_UNSTRUCTURED, Type.NAME);
+        b.setProperty("foo", "bye doc bye");
+        b.setProperty("loc", "1");
+        root.commit();
+
+        String query = "select [jcr:path] from [nt:base] where contains(*,'doc') " +
+                "AND isdescendantnode('/" + SUBTREE + "')";
+
+        Iterator<String> results = executeQuery(query, Query.JCR_SQL2, true).iterator();
+        assertTrue(results.hasNext());
+        assertEquals("/" + SUBTREE + "/a", results.next());
+        assertTrue(results.hasNext());
+        assertEquals("/" + SUBTREE + "/b", results.next());
+        assertFalse(results.hasNext());
+    }
+}

Propchange: jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SubtreeSolrIndexIT.java
------------------------------------------------------------------------------
    svn:eol-style = native