From 3dcf8ea75055ce8da711a780f3372bb400b293b0 Mon Sep 17 00:00:00 2001 From: "ievgen.degtiarenko" Date: Wed, 2 Jul 2025 15:00:52 +0200 Subject: [PATCH 1/2] Integration test for esql index resolution --- .../xpack/esql/plugin/IndexResolutionIT.java | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/IndexResolutionIT.java diff --git a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/IndexResolutionIT.java b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/IndexResolutionIT.java new file mode 100644 index 0000000000000..fafc2e7c4823f --- /dev/null +++ b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/IndexResolutionIT.java @@ -0,0 +1,91 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +package org.elasticsearch.xpack.esql.plugin; + +import org.elasticsearch.cluster.block.ClusterBlockException; +import org.elasticsearch.xpack.esql.VerificationException; +import org.elasticsearch.xpack.esql.action.AbstractEsqlIntegTestCase; +import org.elasticsearch.xpack.esql.action.EsqlQueryResponse; + +import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; +import static org.elasticsearch.xpack.esql.action.EsqlQueryRequest.syncEsqlQueryRequest; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; + +public class IndexResolutionIT extends AbstractEsqlIntegTestCase { + + public void testResolvesConcreteIndex() { + assertAcked(client().admin().indices().prepareCreate("index-1")); + indexRandom(true, "index-1", 10); + + try (var response = run(syncEsqlQueryRequest().query("FROM index-1"))) { + assertOk(response); + } + } + + public void testResolvesAlias() { + assertAcked(client().admin().indices().prepareCreate("index-1")); + indexRandom(true, "index-1", 10); + assertAcked(client().admin().indices().prepareAliases(TEST_REQUEST_TIMEOUT, TEST_REQUEST_TIMEOUT).addAlias("index-1", "alias-1")); + + try (var response = run(syncEsqlQueryRequest().query("FROM alias-1"))) { + assertOk(response); + } + } + + public void testResolvesDataStream() { + // TODO + } + + public void testResolvesPattern() { + assertAcked(client().admin().indices().prepareCreate("index-1")); + indexRandom(true, "index-1", 10); + assertAcked(client().admin().indices().prepareCreate("index-2")); + indexRandom(true, "index-2", 10); + + try (var response = run(syncEsqlQueryRequest().query("FROM index-*"))) { + assertOk(response); + } + } + + public void testDoesNotResolveMissingIndex() { + expectThrows( + VerificationException.class, + containsString("Unknown index [no-such-index]"), + () -> run(syncEsqlQueryRequest().query("FROM no-such-index")) + ); + } + + public void testDoesNotResolveEmptyPattern() { + expectThrows( + VerificationException.class, + containsString("Unknown index [index-*]"), + () -> run(syncEsqlQueryRequest().query("FROM index-*")) + ); + } + + public void testDoesNotResolveClosedIndex() { + assertAcked(client().admin().indices().prepareCreate("index-1")); + indexRandom(true, "index-1", 10); + assertAcked(client().admin().indices().prepareClose("index-1")); + + expectThrows( + ClusterBlockException.class, + containsString("index [index-1] blocked by: [FORBIDDEN/4/index closed]"), + () -> run(syncEsqlQueryRequest().query("FROM index-1")) + ); + } + + public void testPartialResolution() { + // TODO + } + + private static void assertOk(EsqlQueryResponse response) { + assertThat(response.isPartial(), equalTo(false)); + } +} From d31fa8f643ac42d852275b9853c27875b261ce0e Mon Sep 17 00:00:00 2001 From: "ievgen.degtiarenko" Date: Wed, 2 Jul 2025 16:41:34 +0200 Subject: [PATCH 2/2] implement todos --- .../xpack/esql/plugin/IndexResolutionIT.java | 50 ++++++++++++++++++- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/IndexResolutionIT.java b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/IndexResolutionIT.java index fafc2e7c4823f..6d9d086718918 100644 --- a/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/IndexResolutionIT.java +++ b/x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/plugin/IndexResolutionIT.java @@ -7,11 +7,21 @@ package org.elasticsearch.xpack.esql.plugin; +import org.elasticsearch.action.admin.indices.template.put.TransportPutComposableIndexTemplateAction; +import org.elasticsearch.action.datastreams.CreateDataStreamAction; import org.elasticsearch.cluster.block.ClusterBlockException; +import org.elasticsearch.cluster.metadata.ComposableIndexTemplate; +import org.elasticsearch.common.util.CollectionUtils; +import org.elasticsearch.datastreams.DataStreamsPlugin; +import org.elasticsearch.index.IndexNotFoundException; +import org.elasticsearch.plugins.Plugin; import org.elasticsearch.xpack.esql.VerificationException; import org.elasticsearch.xpack.esql.action.AbstractEsqlIntegTestCase; import org.elasticsearch.xpack.esql.action.EsqlQueryResponse; +import java.util.Collection; +import java.util.List; + import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.elasticsearch.xpack.esql.action.EsqlQueryRequest.syncEsqlQueryRequest; import static org.hamcrest.Matchers.containsString; @@ -19,6 +29,11 @@ public class IndexResolutionIT extends AbstractEsqlIntegTestCase { + @Override + protected Collection> nodePlugins() { + return CollectionUtils.appendToCopy(super.nodePlugins(), DataStreamsPlugin.class); + } + public void testResolvesConcreteIndex() { assertAcked(client().admin().indices().prepareCreate("index-1")); indexRandom(true, "index-1", 10); @@ -39,7 +54,27 @@ public void testResolvesAlias() { } public void testResolvesDataStream() { - // TODO + assertAcked( + client().execute( + TransportPutComposableIndexTemplateAction.TYPE, + new TransportPutComposableIndexTemplateAction.Request("data-stream-1-template").indexTemplate( + ComposableIndexTemplate.builder() + .indexPatterns(List.of("data-stream-1*")) + .dataStreamTemplate(new ComposableIndexTemplate.DataStreamTemplate()) + .build() + ) + ) + ); + assertAcked( + client().execute( + CreateDataStreamAction.INSTANCE, + new CreateDataStreamAction.Request(TEST_REQUEST_TIMEOUT, TEST_REQUEST_TIMEOUT, "data-stream-1") + ) + ); + + try (var response = run(syncEsqlQueryRequest().query("FROM data-stream-1"))) { + assertOk(response); + } } public void testResolvesPattern() { @@ -82,7 +117,18 @@ public void testDoesNotResolveClosedIndex() { } public void testPartialResolution() { - // TODO + assertAcked(client().admin().indices().prepareCreate("index-1")); + assertAcked(client().admin().indices().prepareCreate("index-2")); + indexRandom(true, "index-2", 10); + + try (var response = run(syncEsqlQueryRequest().query("FROM index-1,nonexisting"))) { + assertOk(response); + } + expectThrows( + IndexNotFoundException.class, + equalTo("no such index [nonexisting]"), + () -> run(syncEsqlQueryRequest().query("FROM index-2,nonexisting")) + ); } private static void assertOk(EsqlQueryResponse response) {