nfsantos commented on code in PR #697:
URL: https://github.com/apache/jackrabbit-oak/pull/697#discussion_r976447576


##########
oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticIndexPlannerCommonTest.java:
##########
@@ -0,0 +1,233 @@
+/*
+ * 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.elastic;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.plugins.index.IndexPlannerCommonTest;
+import org.apache.jackrabbit.oak.plugins.index.IndexUpdateProvider;
+import org.apache.jackrabbit.oak.plugins.index.TestUtil;
+import org.apache.jackrabbit.oak.plugins.index.TestUtils;
+import 
org.apache.jackrabbit.oak.plugins.index.elastic.index.ElasticIndexEditorProvider;
+import 
org.apache.jackrabbit.oak.plugins.index.elastic.query.ElasticIndexPlanner;
+import 
org.apache.jackrabbit.oak.plugins.index.elastic.util.ElasticIndexDefinitionBuilder;
+import org.apache.jackrabbit.oak.plugins.index.search.FulltextIndexConstants;
+import org.apache.jackrabbit.oak.plugins.index.search.IndexDefinition;
+import org.apache.jackrabbit.oak.plugins.index.search.IndexNode;
+import 
org.apache.jackrabbit.oak.plugins.index.search.spi.query.FulltextIndexPlanner;
+import 
org.apache.jackrabbit.oak.plugins.index.search.util.IndexDefinitionBuilder;
+import org.apache.jackrabbit.oak.query.index.FilterImpl;
+import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
+import org.apache.jackrabbit.oak.spi.commit.EditorHook;
+import org.apache.jackrabbit.oak.spi.query.Filter;
+import org.apache.jackrabbit.oak.spi.query.QueryIndex;
+import org.apache.jackrabbit.oak.spi.query.fulltext.FullTextParser;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.stats.StatisticsProvider;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.junit.After;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.contrib.java.lang.system.ProvideSystemProperty;
+import org.junit.contrib.java.lang.system.RestoreSystemProperties;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.collect.ImmutableSet.of;
+import static javax.jcr.PropertyType.TYPENAME_STRING;
+import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
+import static org.apache.jackrabbit.oak.api.Type.NAME;
+import static org.apache.jackrabbit.oak.api.Type.STRINGS;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.ASYNC_PROPERTY_NAME;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NODE_TYPE;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.REINDEX_PROPERTY_NAME;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.TYPE_PROPERTY_NAME;
+import static 
org.apache.jackrabbit.oak.plugins.memory.PropertyStates.createProperty;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class ElasticIndexPlannerCommonTest extends IndexPlannerCommonTest {
+
+    @ClassRule
+    public static final ElasticConnectionRule elasticRule =
+            new 
ElasticConnectionRule(ElasticTestUtils.ELASTIC_CONNECTION_STRING);
+
+    // Default refresh is 1 minute - so we need to lower that otherwise test 
would need to wait at least 1 minute
+    // before it can get the estimated doc count from the remote ES index
+    @Rule
+    public final ProvideSystemProperty updateSystemProperties
+            = new ProvideSystemProperty("oak.elastic.statsRefreshSeconds", 
"5");
+
+    @Rule
+    public final RestoreSystemProperties restoreSystemProperties = new 
RestoreSystemProperties();
+
+    private final ElasticConnection esConnection;
+    private final ElasticIndexTracker indexTracker;
+    private EditorHook HOOK;
+
+    public ElasticIndexPlannerCommonTest() {
+        indexOptions = new ElasticIndexOptions();
+        this.esConnection = elasticRule.useDocker() ? 
elasticRule.getElasticConnectionForDocker() :
+                elasticRule.getElasticConnectionFromString();
+        this.indexTracker = new ElasticIndexTracker(esConnection, new 
ElasticMetricHandler(StatisticsProvider.NOOP));
+        HOOK = new EditorHook(new IndexUpdateProvider(new 
ElasticIndexEditorProvider(indexTracker, esConnection, null)));
+    }
+
+    @After
+    public void after() {
+        if (esConnection != null) {
+            try {
+                
esConnection.getClient().indices().delete(d->d.index(esConnection.getIndexPrefix()
 + "*"));
+                esConnection.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+
+    private void createSampleDirectory() throws IOException, 
CommitFailedException {
+        createSampleDirectory(1);
+    }
+
+    private void createSampleDirectory(long numOfDocs) throws 
CommitFailedException {
+        NodeState before = builder.getNodeState();
+        NodeBuilder testBuilder = builder.child("test");
+
+        for (int i =0 ; i < numOfDocs ; i++) {
+            testBuilder.child("child" + i).setProperty("foo", "bar" + i);
+        }
+
+        NodeState after = builder.getNodeState();
+        NodeState indexed = HOOK.processCommit(before, after, 
CommitInfo.EMPTY);
+        indexTracker.update(indexed);
+    }
+
+    // This is difference in test implementation from lucene
+    // We are directly adding the content in the IndexWriter for lucene - so 
we can maintain what nodes to add there
+    // But for elastic we add the documents to index via normal commit hooks - 
so in case of fulltext -
+    // even the repo nodes get added
+    // and the doc count is different from lucene
+    @Override
+    @Test
+    public void fulltextIndexCost() throws Exception {
+        NodeBuilder index = builder.child(INDEX_DEFINITIONS_NAME);
+        NodeBuilder defn = getIndexDefinitionNodeBuilder(index, indexName,
+                of(TYPENAME_STRING));
+        TestUtil.useV2(defn);
+
+        long numofDocs = IndexDefinition.DEFAULT_ENTRY_COUNT + 100;

Review Comment:
   Use camel case here: `numOfDoc`. This same variable appears below with full 
camel case.



##########
oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticIndexPlannerCommonTest.java:
##########
@@ -0,0 +1,233 @@
+/*
+ * 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.elastic;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.plugins.index.IndexPlannerCommonTest;
+import org.apache.jackrabbit.oak.plugins.index.IndexUpdateProvider;
+import org.apache.jackrabbit.oak.plugins.index.TestUtil;
+import org.apache.jackrabbit.oak.plugins.index.TestUtils;
+import 
org.apache.jackrabbit.oak.plugins.index.elastic.index.ElasticIndexEditorProvider;
+import 
org.apache.jackrabbit.oak.plugins.index.elastic.query.ElasticIndexPlanner;
+import 
org.apache.jackrabbit.oak.plugins.index.elastic.util.ElasticIndexDefinitionBuilder;
+import org.apache.jackrabbit.oak.plugins.index.search.FulltextIndexConstants;
+import org.apache.jackrabbit.oak.plugins.index.search.IndexDefinition;
+import org.apache.jackrabbit.oak.plugins.index.search.IndexNode;
+import 
org.apache.jackrabbit.oak.plugins.index.search.spi.query.FulltextIndexPlanner;
+import 
org.apache.jackrabbit.oak.plugins.index.search.util.IndexDefinitionBuilder;
+import org.apache.jackrabbit.oak.query.index.FilterImpl;
+import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
+import org.apache.jackrabbit.oak.spi.commit.EditorHook;
+import org.apache.jackrabbit.oak.spi.query.Filter;
+import org.apache.jackrabbit.oak.spi.query.QueryIndex;
+import org.apache.jackrabbit.oak.spi.query.fulltext.FullTextParser;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.stats.StatisticsProvider;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.junit.After;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.contrib.java.lang.system.ProvideSystemProperty;
+import org.junit.contrib.java.lang.system.RestoreSystemProperties;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.collect.ImmutableSet.of;
+import static javax.jcr.PropertyType.TYPENAME_STRING;
+import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
+import static org.apache.jackrabbit.oak.api.Type.NAME;
+import static org.apache.jackrabbit.oak.api.Type.STRINGS;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.ASYNC_PROPERTY_NAME;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NODE_TYPE;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.REINDEX_PROPERTY_NAME;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.TYPE_PROPERTY_NAME;
+import static 
org.apache.jackrabbit.oak.plugins.memory.PropertyStates.createProperty;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class ElasticIndexPlannerCommonTest extends IndexPlannerCommonTest {
+
+    @ClassRule
+    public static final ElasticConnectionRule elasticRule =
+            new 
ElasticConnectionRule(ElasticTestUtils.ELASTIC_CONNECTION_STRING);
+
+    // Default refresh is 1 minute - so we need to lower that otherwise test 
would need to wait at least 1 minute
+    // before it can get the estimated doc count from the remote ES index
+    @Rule
+    public final ProvideSystemProperty updateSystemProperties
+            = new ProvideSystemProperty("oak.elastic.statsRefreshSeconds", 
"5");
+
+    @Rule
+    public final RestoreSystemProperties restoreSystemProperties = new 
RestoreSystemProperties();
+
+    private final ElasticConnection esConnection;
+    private final ElasticIndexTracker indexTracker;
+    private EditorHook HOOK;
+
+    public ElasticIndexPlannerCommonTest() {
+        indexOptions = new ElasticIndexOptions();
+        this.esConnection = elasticRule.useDocker() ? 
elasticRule.getElasticConnectionForDocker() :
+                elasticRule.getElasticConnectionFromString();
+        this.indexTracker = new ElasticIndexTracker(esConnection, new 
ElasticMetricHandler(StatisticsProvider.NOOP));
+        HOOK = new EditorHook(new IndexUpdateProvider(new 
ElasticIndexEditorProvider(indexTracker, esConnection, null)));
+    }
+
+    @After
+    public void after() {
+        if (esConnection != null) {
+            try {
+                
esConnection.getClient().indices().delete(d->d.index(esConnection.getIndexPrefix()
 + "*"));
+                esConnection.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+
+    private void createSampleDirectory() throws IOException, 
CommitFailedException {
+        createSampleDirectory(1);
+    }
+
+    private void createSampleDirectory(long numOfDocs) throws 
CommitFailedException {
+        NodeState before = builder.getNodeState();
+        NodeBuilder testBuilder = builder.child("test");
+
+        for (int i =0 ; i < numOfDocs ; i++) {
+            testBuilder.child("child" + i).setProperty("foo", "bar" + i);
+        }
+
+        NodeState after = builder.getNodeState();
+        NodeState indexed = HOOK.processCommit(before, after, 
CommitInfo.EMPTY);
+        indexTracker.update(indexed);
+    }
+
+    // This is difference in test implementation from lucene
+    // We are directly adding the content in the IndexWriter for lucene - so 
we can maintain what nodes to add there
+    // But for elastic we add the documents to index via normal commit hooks - 
so in case of fulltext -
+    // even the repo nodes get added
+    // and the doc count is different from lucene
+    @Override
+    @Test
+    public void fulltextIndexCost() throws Exception {
+        NodeBuilder index = builder.child(INDEX_DEFINITIONS_NAME);
+        NodeBuilder defn = getIndexDefinitionNodeBuilder(index, indexName,
+                of(TYPENAME_STRING));
+        TestUtil.useV2(defn);
+
+        long numofDocs = IndexDefinition.DEFAULT_ENTRY_COUNT + 100;
+        IndexNode node = createIndexNode(getIndexDefinition(root, 
defn.getNodeState(), "/oak:index/" + indexName), numofDocs);
+        FilterImpl filter = createFilter("nt:base");
+        filter.setFullTextConstraint(FullTextParser.parse(".", "mountain"));
+
+        TestUtils.assertEventually(() -> {
+            FulltextIndexPlanner planner = getIndexPlanner(node, "/oak:index/" 
+ indexName, filter, Collections.<QueryIndex.OrderEntry>emptyList());
+
+            QueryIndex.IndexPlan plan = planner.getPlan();
+            assertNotNull(plan);
+            assertTrue(plan.getEstimatedEntryCount() > numofDocs);
+
+        }, 4500*3);

Review Comment:
   I don't understand the intention behind writing 4500*3 instead of 13500. 
   A suggestion to improve readability: use the class `Duration` instead of 
using long to represent the waiting time. If you change the method 
assertEventually() to accept a duration, then we can specify the durations as 
`Duration.ofSeconds(5)` or `Duration.ofMillis(5000)` which is more readable and 
less error-prone.



##########
oak-search/src/test/java/org/apache/jackrabbit/oak/plugins/index/IndexQuerySQL2OptimisationCommonTest.java:
##########
@@ -172,17 +152,19 @@ public void oak2660() throws Exception {
         }
 
         final String statement =
-            "SELECT * " +
-            "FROM [" + NT_UNSTRUCTURED + "] AS c " +
-            "WHERE " +
-            "( " +
-            "c.[" + name + "] = '" + yes + "' " +
-            "OR CONTAINS(c.[" + surname + "], '" + yes + "') " +
-            "OR CONTAINS(c.[" + description + "], '" + yes + "') " +
-            ") " +
-            "AND ISDESCENDANTNODE(c, '" + content.getPath() + "') " +
-            "ORDER BY " + added + " DESC ";
-
-        assertQuery(statement, SQL2, expected);
+                "SELECT * " +
+                        "FROM [" + NT_UNSTRUCTURED + "] AS c " +
+                        "WHERE " +
+                        "( " +
+                        "c.[" + name + "] = '" + yes + "' " +
+                        "OR CONTAINS(c.[" + surname + "], '" + yes + "') " +
+                        "OR CONTAINS(c.[" + description + "], '" + yes + "') " 
+
+                        ") " +
+                        "AND ISDESCENDANTNODE(c, '" + content.getPath() + "') 
" +
+                        "ORDER BY " + added + " DESC ";
+
+        TestUtils.assertEventually(() -> assertQuery(statement, SQL2, 
expected), 3000 * 5);

Review Comment:
   Why is there a TestUtils and a TestUtil? Can this be merged in a single 
class?



##########
oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticIndexPlannerCommonTest.java:
##########
@@ -0,0 +1,233 @@
+/*
+ * 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.elastic;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.plugins.index.IndexPlannerCommonTest;
+import org.apache.jackrabbit.oak.plugins.index.IndexUpdateProvider;
+import org.apache.jackrabbit.oak.plugins.index.TestUtil;
+import org.apache.jackrabbit.oak.plugins.index.TestUtils;
+import 
org.apache.jackrabbit.oak.plugins.index.elastic.index.ElasticIndexEditorProvider;
+import 
org.apache.jackrabbit.oak.plugins.index.elastic.query.ElasticIndexPlanner;
+import 
org.apache.jackrabbit.oak.plugins.index.elastic.util.ElasticIndexDefinitionBuilder;
+import org.apache.jackrabbit.oak.plugins.index.search.FulltextIndexConstants;
+import org.apache.jackrabbit.oak.plugins.index.search.IndexDefinition;
+import org.apache.jackrabbit.oak.plugins.index.search.IndexNode;
+import 
org.apache.jackrabbit.oak.plugins.index.search.spi.query.FulltextIndexPlanner;
+import 
org.apache.jackrabbit.oak.plugins.index.search.util.IndexDefinitionBuilder;
+import org.apache.jackrabbit.oak.query.index.FilterImpl;
+import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
+import org.apache.jackrabbit.oak.spi.commit.EditorHook;
+import org.apache.jackrabbit.oak.spi.query.Filter;
+import org.apache.jackrabbit.oak.spi.query.QueryIndex;
+import org.apache.jackrabbit.oak.spi.query.fulltext.FullTextParser;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.stats.StatisticsProvider;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.junit.After;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.contrib.java.lang.system.ProvideSystemProperty;
+import org.junit.contrib.java.lang.system.RestoreSystemProperties;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.collect.ImmutableSet.of;
+import static javax.jcr.PropertyType.TYPENAME_STRING;
+import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
+import static org.apache.jackrabbit.oak.api.Type.NAME;
+import static org.apache.jackrabbit.oak.api.Type.STRINGS;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.ASYNC_PROPERTY_NAME;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NODE_TYPE;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.REINDEX_PROPERTY_NAME;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.TYPE_PROPERTY_NAME;
+import static 
org.apache.jackrabbit.oak.plugins.memory.PropertyStates.createProperty;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class ElasticIndexPlannerCommonTest extends IndexPlannerCommonTest {
+
+    @ClassRule
+    public static final ElasticConnectionRule elasticRule =
+            new 
ElasticConnectionRule(ElasticTestUtils.ELASTIC_CONNECTION_STRING);
+
+    // Default refresh is 1 minute - so we need to lower that otherwise test 
would need to wait at least 1 minute
+    // before it can get the estimated doc count from the remote ES index
+    @Rule
+    public final ProvideSystemProperty updateSystemProperties
+            = new ProvideSystemProperty("oak.elastic.statsRefreshSeconds", 
"5");
+
+    @Rule
+    public final RestoreSystemProperties restoreSystemProperties = new 
RestoreSystemProperties();
+
+    private final ElasticConnection esConnection;
+    private final ElasticIndexTracker indexTracker;
+    private EditorHook HOOK;
+
+    public ElasticIndexPlannerCommonTest() {
+        indexOptions = new ElasticIndexOptions();
+        this.esConnection = elasticRule.useDocker() ? 
elasticRule.getElasticConnectionForDocker() :
+                elasticRule.getElasticConnectionFromString();
+        this.indexTracker = new ElasticIndexTracker(esConnection, new 
ElasticMetricHandler(StatisticsProvider.NOOP));
+        HOOK = new EditorHook(new IndexUpdateProvider(new 
ElasticIndexEditorProvider(indexTracker, esConnection, null)));
+    }
+
+    @After
+    public void after() {
+        if (esConnection != null) {
+            try {
+                
esConnection.getClient().indices().delete(d->d.index(esConnection.getIndexPrefix()
 + "*"));
+                esConnection.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+
+    private void createSampleDirectory() throws IOException, 
CommitFailedException {
+        createSampleDirectory(1);
+    }
+
+    private void createSampleDirectory(long numOfDocs) throws 
CommitFailedException {
+        NodeState before = builder.getNodeState();
+        NodeBuilder testBuilder = builder.child("test");
+
+        for (int i =0 ; i < numOfDocs ; i++) {
+            testBuilder.child("child" + i).setProperty("foo", "bar" + i);
+        }
+
+        NodeState after = builder.getNodeState();
+        NodeState indexed = HOOK.processCommit(before, after, 
CommitInfo.EMPTY);
+        indexTracker.update(indexed);
+    }
+
+    // This is difference in test implementation from lucene
+    // We are directly adding the content in the IndexWriter for lucene - so 
we can maintain what nodes to add there
+    // But for elastic we add the documents to index via normal commit hooks - 
so in case of fulltext -
+    // even the repo nodes get added
+    // and the doc count is different from lucene
+    @Override
+    @Test
+    public void fulltextIndexCost() throws Exception {
+        NodeBuilder index = builder.child(INDEX_DEFINITIONS_NAME);
+        NodeBuilder defn = getIndexDefinitionNodeBuilder(index, indexName,
+                of(TYPENAME_STRING));
+        TestUtil.useV2(defn);
+
+        long numofDocs = IndexDefinition.DEFAULT_ENTRY_COUNT + 100;
+        IndexNode node = createIndexNode(getIndexDefinition(root, 
defn.getNodeState(), "/oak:index/" + indexName), numofDocs);
+        FilterImpl filter = createFilter("nt:base");
+        filter.setFullTextConstraint(FullTextParser.parse(".", "mountain"));
+
+        TestUtils.assertEventually(() -> {
+            FulltextIndexPlanner planner = getIndexPlanner(node, "/oak:index/" 
+ indexName, filter, Collections.<QueryIndex.OrderEntry>emptyList());
+
+            QueryIndex.IndexPlan plan = planner.getPlan();
+            assertNotNull(plan);
+            assertTrue(plan.getEstimatedEntryCount() > numofDocs);
+
+        }, 4500*3);
+
+
+    }
+
+    @Override
+    protected IndexNode createIndexNode(IndexDefinition defn) throws 
IOException {
+        try {
+            createSampleDirectory();
+        } catch (CommitFailedException e) {
+            e.printStackTrace();

Review Comment:
   Use a logger instead. The test is not aborted if the sample directory did 
not commit. Is this intentional?



##########
oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticIndexPlannerCommonTest.java:
##########
@@ -0,0 +1,233 @@
+/*
+ * 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.elastic;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.plugins.index.IndexPlannerCommonTest;
+import org.apache.jackrabbit.oak.plugins.index.IndexUpdateProvider;
+import org.apache.jackrabbit.oak.plugins.index.TestUtil;
+import org.apache.jackrabbit.oak.plugins.index.TestUtils;
+import 
org.apache.jackrabbit.oak.plugins.index.elastic.index.ElasticIndexEditorProvider;
+import 
org.apache.jackrabbit.oak.plugins.index.elastic.query.ElasticIndexPlanner;
+import 
org.apache.jackrabbit.oak.plugins.index.elastic.util.ElasticIndexDefinitionBuilder;
+import org.apache.jackrabbit.oak.plugins.index.search.FulltextIndexConstants;
+import org.apache.jackrabbit.oak.plugins.index.search.IndexDefinition;
+import org.apache.jackrabbit.oak.plugins.index.search.IndexNode;
+import 
org.apache.jackrabbit.oak.plugins.index.search.spi.query.FulltextIndexPlanner;
+import 
org.apache.jackrabbit.oak.plugins.index.search.util.IndexDefinitionBuilder;
+import org.apache.jackrabbit.oak.query.index.FilterImpl;
+import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
+import org.apache.jackrabbit.oak.spi.commit.EditorHook;
+import org.apache.jackrabbit.oak.spi.query.Filter;
+import org.apache.jackrabbit.oak.spi.query.QueryIndex;
+import org.apache.jackrabbit.oak.spi.query.fulltext.FullTextParser;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.stats.StatisticsProvider;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.junit.After;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.contrib.java.lang.system.ProvideSystemProperty;
+import org.junit.contrib.java.lang.system.RestoreSystemProperties;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.collect.ImmutableSet.of;
+import static javax.jcr.PropertyType.TYPENAME_STRING;
+import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
+import static org.apache.jackrabbit.oak.api.Type.NAME;
+import static org.apache.jackrabbit.oak.api.Type.STRINGS;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.ASYNC_PROPERTY_NAME;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NODE_TYPE;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.REINDEX_PROPERTY_NAME;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.TYPE_PROPERTY_NAME;
+import static 
org.apache.jackrabbit.oak.plugins.memory.PropertyStates.createProperty;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class ElasticIndexPlannerCommonTest extends IndexPlannerCommonTest {
+
+    @ClassRule
+    public static final ElasticConnectionRule elasticRule =
+            new 
ElasticConnectionRule(ElasticTestUtils.ELASTIC_CONNECTION_STRING);
+
+    // Default refresh is 1 minute - so we need to lower that otherwise test 
would need to wait at least 1 minute
+    // before it can get the estimated doc count from the remote ES index
+    @Rule
+    public final ProvideSystemProperty updateSystemProperties
+            = new ProvideSystemProperty("oak.elastic.statsRefreshSeconds", 
"5");
+
+    @Rule
+    public final RestoreSystemProperties restoreSystemProperties = new 
RestoreSystemProperties();
+
+    private final ElasticConnection esConnection;
+    private final ElasticIndexTracker indexTracker;
+    private EditorHook HOOK;
+
+    public ElasticIndexPlannerCommonTest() {
+        indexOptions = new ElasticIndexOptions();
+        this.esConnection = elasticRule.useDocker() ? 
elasticRule.getElasticConnectionForDocker() :
+                elasticRule.getElasticConnectionFromString();
+        this.indexTracker = new ElasticIndexTracker(esConnection, new 
ElasticMetricHandler(StatisticsProvider.NOOP));
+        HOOK = new EditorHook(new IndexUpdateProvider(new 
ElasticIndexEditorProvider(indexTracker, esConnection, null)));

Review Comment:
   Consistency: use `this.HOOK`. 
   Why is the variable in all upper?



##########
oak-search/pom.xml:
##########
@@ -129,6 +129,10 @@
             <version>${tika.version}</version>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>commons-lang</groupId>
+            <artifactId>commons-lang</artifactId>
+        </dependency>

Review Comment:
   Is it possible to add this dependency only to the test scope? AFAIK, this PR 
only changes the test files of the oak-search package, so it should not be 
necessary to add this package to the compile/runtime scope. 



##########
oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticIndexPlannerCommonTest.java:
##########
@@ -0,0 +1,233 @@
+/*
+ * 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.elastic;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.plugins.index.IndexPlannerCommonTest;
+import org.apache.jackrabbit.oak.plugins.index.IndexUpdateProvider;
+import org.apache.jackrabbit.oak.plugins.index.TestUtil;
+import org.apache.jackrabbit.oak.plugins.index.TestUtils;
+import 
org.apache.jackrabbit.oak.plugins.index.elastic.index.ElasticIndexEditorProvider;
+import 
org.apache.jackrabbit.oak.plugins.index.elastic.query.ElasticIndexPlanner;
+import 
org.apache.jackrabbit.oak.plugins.index.elastic.util.ElasticIndexDefinitionBuilder;
+import org.apache.jackrabbit.oak.plugins.index.search.FulltextIndexConstants;
+import org.apache.jackrabbit.oak.plugins.index.search.IndexDefinition;
+import org.apache.jackrabbit.oak.plugins.index.search.IndexNode;
+import 
org.apache.jackrabbit.oak.plugins.index.search.spi.query.FulltextIndexPlanner;
+import 
org.apache.jackrabbit.oak.plugins.index.search.util.IndexDefinitionBuilder;
+import org.apache.jackrabbit.oak.query.index.FilterImpl;
+import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
+import org.apache.jackrabbit.oak.spi.commit.EditorHook;
+import org.apache.jackrabbit.oak.spi.query.Filter;
+import org.apache.jackrabbit.oak.spi.query.QueryIndex;
+import org.apache.jackrabbit.oak.spi.query.fulltext.FullTextParser;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.stats.StatisticsProvider;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.junit.After;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.contrib.java.lang.system.ProvideSystemProperty;
+import org.junit.contrib.java.lang.system.RestoreSystemProperties;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.collect.ImmutableSet.of;
+import static javax.jcr.PropertyType.TYPENAME_STRING;
+import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
+import static org.apache.jackrabbit.oak.api.Type.NAME;
+import static org.apache.jackrabbit.oak.api.Type.STRINGS;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.ASYNC_PROPERTY_NAME;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NODE_TYPE;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.REINDEX_PROPERTY_NAME;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.TYPE_PROPERTY_NAME;
+import static 
org.apache.jackrabbit.oak.plugins.memory.PropertyStates.createProperty;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class ElasticIndexPlannerCommonTest extends IndexPlannerCommonTest {
+
+    @ClassRule
+    public static final ElasticConnectionRule elasticRule =
+            new 
ElasticConnectionRule(ElasticTestUtils.ELASTIC_CONNECTION_STRING);
+
+    // Default refresh is 1 minute - so we need to lower that otherwise test 
would need to wait at least 1 minute
+    // before it can get the estimated doc count from the remote ES index
+    @Rule
+    public final ProvideSystemProperty updateSystemProperties
+            = new ProvideSystemProperty("oak.elastic.statsRefreshSeconds", 
"5");
+
+    @Rule
+    public final RestoreSystemProperties restoreSystemProperties = new 
RestoreSystemProperties();
+
+    private final ElasticConnection esConnection;
+    private final ElasticIndexTracker indexTracker;
+    private EditorHook HOOK;
+
+    public ElasticIndexPlannerCommonTest() {
+        indexOptions = new ElasticIndexOptions();
+        this.esConnection = elasticRule.useDocker() ? 
elasticRule.getElasticConnectionForDocker() :
+                elasticRule.getElasticConnectionFromString();
+        this.indexTracker = new ElasticIndexTracker(esConnection, new 
ElasticMetricHandler(StatisticsProvider.NOOP));
+        HOOK = new EditorHook(new IndexUpdateProvider(new 
ElasticIndexEditorProvider(indexTracker, esConnection, null)));
+    }
+
+    @After
+    public void after() {
+        if (esConnection != null) {
+            try {
+                
esConnection.getClient().indices().delete(d->d.index(esConnection.getIndexPrefix()
 + "*"));
+                esConnection.close();
+            } catch (IOException e) {
+                e.printStackTrace();

Review Comment:
   Use a logger instead of writing directly to console.



##########
oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticIndexPlannerCommonTest.java:
##########
@@ -0,0 +1,233 @@
+/*
+ * 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.elastic;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.plugins.index.IndexPlannerCommonTest;
+import org.apache.jackrabbit.oak.plugins.index.IndexUpdateProvider;
+import org.apache.jackrabbit.oak.plugins.index.TestUtil;
+import org.apache.jackrabbit.oak.plugins.index.TestUtils;
+import 
org.apache.jackrabbit.oak.plugins.index.elastic.index.ElasticIndexEditorProvider;
+import 
org.apache.jackrabbit.oak.plugins.index.elastic.query.ElasticIndexPlanner;
+import 
org.apache.jackrabbit.oak.plugins.index.elastic.util.ElasticIndexDefinitionBuilder;
+import org.apache.jackrabbit.oak.plugins.index.search.FulltextIndexConstants;
+import org.apache.jackrabbit.oak.plugins.index.search.IndexDefinition;
+import org.apache.jackrabbit.oak.plugins.index.search.IndexNode;
+import 
org.apache.jackrabbit.oak.plugins.index.search.spi.query.FulltextIndexPlanner;
+import 
org.apache.jackrabbit.oak.plugins.index.search.util.IndexDefinitionBuilder;
+import org.apache.jackrabbit.oak.query.index.FilterImpl;
+import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
+import org.apache.jackrabbit.oak.spi.commit.EditorHook;
+import org.apache.jackrabbit.oak.spi.query.Filter;
+import org.apache.jackrabbit.oak.spi.query.QueryIndex;
+import org.apache.jackrabbit.oak.spi.query.fulltext.FullTextParser;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.stats.StatisticsProvider;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.junit.After;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.contrib.java.lang.system.ProvideSystemProperty;
+import org.junit.contrib.java.lang.system.RestoreSystemProperties;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.collect.ImmutableSet.of;
+import static javax.jcr.PropertyType.TYPENAME_STRING;
+import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
+import static org.apache.jackrabbit.oak.api.Type.NAME;
+import static org.apache.jackrabbit.oak.api.Type.STRINGS;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.ASYNC_PROPERTY_NAME;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NODE_TYPE;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.REINDEX_PROPERTY_NAME;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.TYPE_PROPERTY_NAME;
+import static 
org.apache.jackrabbit.oak.plugins.memory.PropertyStates.createProperty;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class ElasticIndexPlannerCommonTest extends IndexPlannerCommonTest {
+
+    @ClassRule
+    public static final ElasticConnectionRule elasticRule =
+            new 
ElasticConnectionRule(ElasticTestUtils.ELASTIC_CONNECTION_STRING);
+
+    // Default refresh is 1 minute - so we need to lower that otherwise test 
would need to wait at least 1 minute
+    // before it can get the estimated doc count from the remote ES index
+    @Rule
+    public final ProvideSystemProperty updateSystemProperties
+            = new ProvideSystemProperty("oak.elastic.statsRefreshSeconds", 
"5");
+
+    @Rule
+    public final RestoreSystemProperties restoreSystemProperties = new 
RestoreSystemProperties();
+
+    private final ElasticConnection esConnection;
+    private final ElasticIndexTracker indexTracker;
+    private EditorHook HOOK;
+
+    public ElasticIndexPlannerCommonTest() {
+        indexOptions = new ElasticIndexOptions();
+        this.esConnection = elasticRule.useDocker() ? 
elasticRule.getElasticConnectionForDocker() :
+                elasticRule.getElasticConnectionFromString();
+        this.indexTracker = new ElasticIndexTracker(esConnection, new 
ElasticMetricHandler(StatisticsProvider.NOOP));
+        HOOK = new EditorHook(new IndexUpdateProvider(new 
ElasticIndexEditorProvider(indexTracker, esConnection, null)));
+    }
+
+    @After
+    public void after() {
+        if (esConnection != null) {
+            try {
+                
esConnection.getClient().indices().delete(d->d.index(esConnection.getIndexPrefix()
 + "*"));
+                esConnection.close();

Review Comment:
   The close should be in a finally block, so that the connection is closed 
even if the previous call to delete the indexes fails.



##########
oak-search-elastic/src/test/java/org/apache/jackrabbit/oak/plugins/index/elastic/ElasticIndexPlannerCommonTest.java:
##########
@@ -0,0 +1,233 @@
+/*
+ * 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.elastic;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.plugins.index.IndexPlannerCommonTest;
+import org.apache.jackrabbit.oak.plugins.index.IndexUpdateProvider;
+import org.apache.jackrabbit.oak.plugins.index.TestUtil;
+import org.apache.jackrabbit.oak.plugins.index.TestUtils;
+import 
org.apache.jackrabbit.oak.plugins.index.elastic.index.ElasticIndexEditorProvider;
+import 
org.apache.jackrabbit.oak.plugins.index.elastic.query.ElasticIndexPlanner;
+import 
org.apache.jackrabbit.oak.plugins.index.elastic.util.ElasticIndexDefinitionBuilder;
+import org.apache.jackrabbit.oak.plugins.index.search.FulltextIndexConstants;
+import org.apache.jackrabbit.oak.plugins.index.search.IndexDefinition;
+import org.apache.jackrabbit.oak.plugins.index.search.IndexNode;
+import 
org.apache.jackrabbit.oak.plugins.index.search.spi.query.FulltextIndexPlanner;
+import 
org.apache.jackrabbit.oak.plugins.index.search.util.IndexDefinitionBuilder;
+import org.apache.jackrabbit.oak.query.index.FilterImpl;
+import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
+import org.apache.jackrabbit.oak.spi.commit.EditorHook;
+import org.apache.jackrabbit.oak.spi.query.Filter;
+import org.apache.jackrabbit.oak.spi.query.QueryIndex;
+import org.apache.jackrabbit.oak.spi.query.fulltext.FullTextParser;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.jackrabbit.oak.stats.StatisticsProvider;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.junit.After;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.contrib.java.lang.system.ProvideSystemProperty;
+import org.junit.contrib.java.lang.system.RestoreSystemProperties;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.collect.ImmutableSet.of;
+import static javax.jcr.PropertyType.TYPENAME_STRING;
+import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
+import static org.apache.jackrabbit.oak.api.Type.NAME;
+import static org.apache.jackrabbit.oak.api.Type.STRINGS;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.ASYNC_PROPERTY_NAME;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NODE_TYPE;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.REINDEX_PROPERTY_NAME;
+import static 
org.apache.jackrabbit.oak.plugins.index.IndexConstants.TYPE_PROPERTY_NAME;
+import static 
org.apache.jackrabbit.oak.plugins.memory.PropertyStates.createProperty;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class ElasticIndexPlannerCommonTest extends IndexPlannerCommonTest {
+
+    @ClassRule
+    public static final ElasticConnectionRule elasticRule =
+            new 
ElasticConnectionRule(ElasticTestUtils.ELASTIC_CONNECTION_STRING);
+
+    // Default refresh is 1 minute - so we need to lower that otherwise test 
would need to wait at least 1 minute
+    // before it can get the estimated doc count from the remote ES index
+    @Rule
+    public final ProvideSystemProperty updateSystemProperties
+            = new ProvideSystemProperty("oak.elastic.statsRefreshSeconds", 
"5");
+
+    @Rule
+    public final RestoreSystemProperties restoreSystemProperties = new 
RestoreSystemProperties();
+
+    private final ElasticConnection esConnection;
+    private final ElasticIndexTracker indexTracker;
+    private EditorHook HOOK;
+
+    public ElasticIndexPlannerCommonTest() {
+        indexOptions = new ElasticIndexOptions();
+        this.esConnection = elasticRule.useDocker() ? 
elasticRule.getElasticConnectionForDocker() :
+                elasticRule.getElasticConnectionFromString();
+        this.indexTracker = new ElasticIndexTracker(esConnection, new 
ElasticMetricHandler(StatisticsProvider.NOOP));
+        HOOK = new EditorHook(new IndexUpdateProvider(new 
ElasticIndexEditorProvider(indexTracker, esConnection, null)));
+    }
+
+    @After
+    public void after() {
+        if (esConnection != null) {
+            try {
+                
esConnection.getClient().indices().delete(d->d.index(esConnection.getIndexPrefix()
 + "*"));
+                esConnection.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+
+    private void createSampleDirectory() throws IOException, 
CommitFailedException {
+        createSampleDirectory(1);
+    }
+
+    private void createSampleDirectory(long numOfDocs) throws 
CommitFailedException {
+        NodeState before = builder.getNodeState();
+        NodeBuilder testBuilder = builder.child("test");
+
+        for (int i =0 ; i < numOfDocs ; i++) {
+            testBuilder.child("child" + i).setProperty("foo", "bar" + i);
+        }
+
+        NodeState after = builder.getNodeState();
+        NodeState indexed = HOOK.processCommit(before, after, 
CommitInfo.EMPTY);
+        indexTracker.update(indexed);
+    }
+
+    // This is difference in test implementation from lucene
+    // We are directly adding the content in the IndexWriter for lucene - so 
we can maintain what nodes to add there
+    // But for elastic we add the documents to index via normal commit hooks - 
so in case of fulltext -
+    // even the repo nodes get added
+    // and the doc count is different from lucene
+    @Override
+    @Test
+    public void fulltextIndexCost() throws Exception {
+        NodeBuilder index = builder.child(INDEX_DEFINITIONS_NAME);
+        NodeBuilder defn = getIndexDefinitionNodeBuilder(index, indexName,
+                of(TYPENAME_STRING));
+        TestUtil.useV2(defn);
+
+        long numofDocs = IndexDefinition.DEFAULT_ENTRY_COUNT + 100;
+        IndexNode node = createIndexNode(getIndexDefinition(root, 
defn.getNodeState(), "/oak:index/" + indexName), numofDocs);
+        FilterImpl filter = createFilter("nt:base");
+        filter.setFullTextConstraint(FullTextParser.parse(".", "mountain"));
+
+        TestUtils.assertEventually(() -> {
+            FulltextIndexPlanner planner = getIndexPlanner(node, "/oak:index/" 
+ indexName, filter, Collections.<QueryIndex.OrderEntry>emptyList());
+
+            QueryIndex.IndexPlan plan = planner.getPlan();
+            assertNotNull(plan);
+            assertTrue(plan.getEstimatedEntryCount() > numofDocs);
+
+        }, 4500*3);
+
+
+    }
+
+    @Override
+    protected IndexNode createIndexNode(IndexDefinition defn) throws 
IOException {
+        try {
+            createSampleDirectory();
+        } catch (CommitFailedException e) {
+            e.printStackTrace();
+        }
+        return new ElasticIndexNodeManager(defn.getIndexPath(), 
builder.getNodeState(), esConnection).getIndexNode();
+    }
+
+    @Override
+    protected IndexNode createIndexNode(IndexDefinition defn, long numOfDocs) 
throws IOException {
+        try {
+            createSampleDirectory(numOfDocs);
+        } catch (CommitFailedException e) {
+            e.printStackTrace();

Review Comment:
   This is being printed directly to sysout. Use a logger instead.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscr...@jackrabbit.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to