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
