|
34 | 34 |
|
35 | 35 | import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
36 | 36 |
|
| 37 | +import org.apache.lucene.index.Term; |
| 38 | +import org.apache.lucene.search.IndexSearcher; |
| 39 | +import org.apache.lucene.search.Query; |
| 40 | +import org.apache.lucene.search.ScoreMode; |
| 41 | +import org.apache.lucene.search.TermQuery; |
| 42 | +import org.apache.lucene.search.Weight; |
37 | 43 | import org.opensearch.action.admin.cluster.health.ClusterHealthResponse;
|
38 | 44 | import org.opensearch.action.admin.cluster.node.stats.NodeStats;
|
39 | 45 | import org.opensearch.action.admin.cluster.node.stats.NodesStatsResponse;
|
|
56 | 62 | import org.opensearch.env.NodeEnvironment;
|
57 | 63 | import org.opensearch.index.IndexSettings;
|
58 | 64 | import org.opensearch.index.cache.request.RequestCacheStats;
|
| 65 | +import org.opensearch.index.query.QueryBuilder; |
59 | 66 | import org.opensearch.index.query.QueryBuilders;
|
| 67 | +import org.opensearch.index.query.QueryShardContext; |
| 68 | +import org.opensearch.index.query.TermQueryBuilder; |
60 | 69 | import org.opensearch.search.aggregations.bucket.global.GlobalAggregationBuilder;
|
61 | 70 | import org.opensearch.search.aggregations.bucket.histogram.DateHistogramInterval;
|
62 | 71 | import org.opensearch.search.aggregations.bucket.histogram.Histogram;
|
|
65 | 74 | import org.opensearch.test.ParameterizedStaticSettingsOpenSearchIntegTestCase;
|
66 | 75 | import org.opensearch.test.hamcrest.OpenSearchAssertions;
|
67 | 76 |
|
| 77 | +import java.io.IOException; |
68 | 78 | import java.nio.file.Files;
|
69 | 79 | import java.nio.file.Path;
|
70 | 80 | import java.time.ZoneId;
|
@@ -768,6 +778,59 @@ public void testDeleteAndCreateSameIndexShardOnSameNode() throws Exception {
|
768 | 778 | assertTrue(stats.getMemorySizeInBytes() == 0);
|
769 | 779 | }
|
770 | 780 |
|
| 781 | + public void testTimedOutQuery() throws Exception { |
| 782 | + // A timed out query should be cached and then invalidated |
| 783 | + Client client = client(); |
| 784 | + String index = "index"; |
| 785 | + assertAcked( |
| 786 | + client.admin() |
| 787 | + .indices() |
| 788 | + .prepareCreate(index) |
| 789 | + .setMapping("k", "type=keyword") |
| 790 | + .setSettings( |
| 791 | + Settings.builder() |
| 792 | + .put(IndicesRequestCache.INDEX_CACHE_REQUEST_ENABLED_SETTING.getKey(), true) |
| 793 | + .put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1) |
| 794 | + .put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0) |
| 795 | + // Disable index refreshing to avoid cache being invalidated mid-test |
| 796 | + .put(IndexSettings.INDEX_REFRESH_INTERVAL_SETTING.getKey(), TimeValue.timeValueMillis(-1)) |
| 797 | + ) |
| 798 | + .get() |
| 799 | + ); |
| 800 | + indexRandom(true, client.prepareIndex(index).setSource("k", "hello")); |
| 801 | + ensureSearchable(index); |
| 802 | + // Force merge the index to ensure there can be no background merges during the subsequent searches that would invalidate the cache |
| 803 | + forceMerge(client, index); |
| 804 | + |
| 805 | + QueryBuilder timeoutQueryBuilder = new TermQueryBuilder("k", "hello") { |
| 806 | + @Override |
| 807 | + protected Query doToQuery(QueryShardContext context) { |
| 808 | + return new TermQuery(new Term("k", "hello")) { |
| 809 | + @Override |
| 810 | + public Weight createWeight(IndexSearcher searcher, ScoreMode scoreMode, float boost) throws IOException { |
| 811 | + // Create the weight before sleeping. Otherwise, TermStates.build() (in the call to super.createWeight()) will |
| 812 | + // sometimes throw an exception on timeout, rather than timing out gracefully. |
| 813 | + Weight result = super.createWeight(searcher, scoreMode, boost); |
| 814 | + try { |
| 815 | + Thread.sleep(500); |
| 816 | + } catch (InterruptedException ignored) {} |
| 817 | + return result; |
| 818 | + } |
| 819 | + }; |
| 820 | + } |
| 821 | + }; |
| 822 | + |
| 823 | + SearchResponse resp = client.prepareSearch(index) |
| 824 | + .setRequestCache(true) |
| 825 | + .setQuery(timeoutQueryBuilder) |
| 826 | + .setTimeout(TimeValue.ZERO) |
| 827 | + .get(); |
| 828 | + assertTrue(resp.isTimedOut()); |
| 829 | + RequestCacheStats requestCacheStats = getRequestCacheStats(client, index); |
| 830 | + // The cache should be empty as the timed-out query was invalidated |
| 831 | + assertEquals(0, requestCacheStats.getMemorySizeInBytes()); |
| 832 | + } |
| 833 | + |
771 | 834 | private Path[] shardDirectory(String server, Index index, int shard) {
|
772 | 835 | NodeEnvironment env = internalCluster().getInstance(NodeEnvironment.class, server);
|
773 | 836 | final Path[] paths = env.availableShardPaths(new ShardId(index, shard));
|
|
0 commit comments