Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,8 @@
import org.apache.lucene.util.BytesRef;
import org.elasticsearch.ExceptionsHelper;
import org.elasticsearch.TransportVersion;
import org.elasticsearch.client.internal.Client;
import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.cluster.RemoteException;
import org.elasticsearch.cluster.metadata.IndexMetadata;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.project.ProjectResolver;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.breaker.CircuitBreaker;
import org.elasticsearch.common.breaker.NoopCircuitBreaker;
Expand All @@ -28,15 +23,11 @@
import org.elasticsearch.common.io.stream.BytesStreamOutput;
import org.elasticsearch.common.lucene.BytesRefs;
import org.elasticsearch.common.regex.Regex;
import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.BigArrays;
import org.elasticsearch.common.util.concurrent.EsExecutors;
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.compute.data.AggregateMetricDoubleBlockBuilder;
import org.elasticsearch.compute.data.BlockFactory;
import org.elasticsearch.compute.data.BlockFactoryProvider;
import org.elasticsearch.compute.data.BlockUtils;
import org.elasticsearch.compute.data.BytesRefBlock;
import org.elasticsearch.compute.data.DoubleBlock;
Expand Down Expand Up @@ -66,18 +57,13 @@
import org.elasticsearch.license.XPackLicenseState;
import org.elasticsearch.logging.LogManager;
import org.elasticsearch.logging.Logger;
import org.elasticsearch.search.SearchService;
import org.elasticsearch.search.aggregations.bucket.geogrid.GeoTileUtils;
import org.elasticsearch.search.aggregations.metrics.TDigestState;
import org.elasticsearch.search.crossproject.CrossProjectModeDecider;
import org.elasticsearch.tasks.TaskCancelledException;
import org.elasticsearch.tdigest.Centroid;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.TransportVersionUtils;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.RemoteTransportException;
import org.elasticsearch.transport.TransportService;
import org.elasticsearch.useragent.api.UserAgentParserRegistry;
import org.elasticsearch.xcontent.XContentType;
import org.elasticsearch.xcontent.json.JsonXContent;
import org.elasticsearch.xpack.core.analytics.mapper.EncodedTDigest;
Expand Down Expand Up @@ -123,8 +109,6 @@
import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.NotEquals;
import org.elasticsearch.xpack.esql.index.IndexResolution;
import org.elasticsearch.xpack.esql.inference.InferenceResolution;
import org.elasticsearch.xpack.esql.inference.InferenceService;
import org.elasticsearch.xpack.esql.inference.InferenceSettings;
import org.elasticsearch.xpack.esql.optimizer.LocalLogicalPlanOptimizer;
import org.elasticsearch.xpack.esql.optimizer.LogicalOptimizerContext;
import org.elasticsearch.xpack.esql.optimizer.LogicalPlanOptimizer;
Expand All @@ -148,10 +132,7 @@
import org.elasticsearch.xpack.esql.plan.logical.local.LocalSupplier;
import org.elasticsearch.xpack.esql.plan.physical.FragmentExec;
import org.elasticsearch.xpack.esql.plan.physical.PhysicalPlan;
import org.elasticsearch.xpack.esql.planner.PlannerSettings;
import org.elasticsearch.xpack.esql.planner.PlannerUtils;
import org.elasticsearch.xpack.esql.plugin.QueryPragmas;
import org.elasticsearch.xpack.esql.plugin.TransportActionServices;
import org.elasticsearch.xpack.esql.session.Configuration;
import org.elasticsearch.xpack.esql.session.EsqlSession;
import org.elasticsearch.xpack.esql.stats.SearchStats;
Expand Down Expand Up @@ -240,9 +221,6 @@
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;

public final class EsqlTestUtils {

Expand Down Expand Up @@ -712,51 +690,6 @@ public static LogicalOptimizerContext unboundLogicalOptimizerContext() {
new XPackLicenseState(() -> 0L)
);

public static final TransportActionServices MOCK_TRANSPORT_ACTION_SERVICES;
static {
ClusterService clusterService = createMockClusterService();
MOCK_TRANSPORT_ACTION_SERVICES = new TransportActionServices(
createMockTransportService(),
mock(SearchService.class),
null,
clusterService,
mock(ProjectResolver.class),
mock(IndexNameExpressionResolver.class),
null,
new InferenceService(mock(Client.class), clusterService),
UserAgentParserRegistry.NOOP,
new BlockFactoryProvider(PlannerUtils.NON_BREAKING_BLOCK_FACTORY),
new PlannerSettings.Holder(clusterService),
CrossProjectModeDecider.NOOP
);
}
Copy link
Copy Markdown
Contributor Author

@idegtiarenko idegtiarenko Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CsvIT uses EsqlTestUtils#classpathResources in order to discover and load spec files.
Since EsqlTestUtils has to be laoded above static block was executed as well, initializing number of non trivial but unused dependencies adding ~1s (highlighted in the profile below) to initialization duration on my machine. Moving this code to its only usage.

Image


private static ClusterService createMockClusterService() {
var service = mock(ClusterService.class);
doReturn(new ClusterName("test-cluster")).when(service).getClusterName();
doReturn(Settings.EMPTY).when(service).getSettings();

// Create ClusterSettings with the required inference settings
Set<Setting<?>> settings = new HashSet<>();
settings.addAll(InferenceSettings.getSettings());
settings.addAll(PlannerSettings.settings());
var clusterSettings = new ClusterSettings(Settings.EMPTY, settings);
doReturn(clusterSettings).when(service).getClusterSettings();
return service;
}

private static TransportService createMockTransportService() {
var service = mock(TransportService.class);
doReturn(createMockThreadPool()).when(service).getThreadPool();
return service;
}

private static ThreadPool createMockThreadPool() {
var threadPool = mock(ThreadPool.class);
doReturn(EsExecutors.DIRECT_EXECUTOR_SERVICE).when(threadPool).executor(anyString());
return threadPool;
}

private EsqlTestUtils() {}

public static Configuration configuration(QueryPragmas pragmas, String query, EsqlStatement statement) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,16 +158,16 @@ public static List<Object[]> readScriptSpec() throws Exception {
return SpecReader.readScriptSpec(urls, specParser());
}

private static java.nio.file.Path nodeConfigDir;

@BeforeClass
public static void setupCluster() throws Exception {
nodeConfigDir = createConfigDir();
long start = System.currentTimeMillis();
logger.info("Creating test cluster");
var nodeDirectory = createTempDir();
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

createTempDir() proved to be expensive in #145543
This reuses single temp dir rather than having a separate one for configuration.

var configDirectory = nodeDirectory.resolve("config");
createCustomRegexConfig(configDirectory);
cluster = new InternalTestCluster(
randomLong(),
createTempDir(),
nodeDirectory,
false,
true,
1,
Expand All @@ -184,7 +184,7 @@ public Settings nodeSettings(int nodeOrdinal, Settings otherSettings) {

@Override
public java.nio.file.Path nodeConfigPath(int nodeOrdinal) {
return nodeConfigDir;
return configDirectory;
}
},
0,
Expand Down Expand Up @@ -550,18 +550,14 @@ public void ensureNoFailures() {
}
}

private static Path createConfigDir() throws IOException {
Path configDir = createTempDir();

private static void createCustomRegexConfig(Path configDir) throws IOException {
// create a subdir for the user-agent with custom regex files so we can test the USER_AGENT with the regex_file option
Path userAgentDir = configDir.resolve("user-agent");
Files.createDirectories(userAgentDir);
try (InputStream is = CsvIT.class.getResourceAsStream("/custom-regexes.yml")) {
assert is != null : "custom-regexes.yml not found on classpath";
Files.copy(is, userAgentDir.resolve("custom-regexes.yml"));
}

return configDir;
}

private static class ResponseListener extends PlainActionFuture<EsqlQueryResponse> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,28 @@
import org.elasticsearch.action.fieldcaps.IndexFieldCapabilitiesBuilder;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.client.internal.Client;
import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.project.ProjectResolver;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.breaker.NoopCircuitBreaker;
import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.BigArrays;
import org.elasticsearch.common.util.concurrent.EsExecutors;
import org.elasticsearch.compute.data.BlockFactory;
import org.elasticsearch.compute.data.BlockFactoryProvider;
import org.elasticsearch.index.IndexMode;
import org.elasticsearch.indices.IndicesExpressionGrouper;
import org.elasticsearch.license.XPackLicenseState;
import org.elasticsearch.search.SearchService;
import org.elasticsearch.search.crossproject.CrossProjectModeDecider;
import org.elasticsearch.telemetry.metric.MeterRegistry;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.threadpool.TestThreadPool;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.xpack.esql.EsqlTestUtils;
import org.elasticsearch.transport.TransportService;
import org.elasticsearch.useragent.api.UserAgentParserRegistry;
import org.elasticsearch.xpack.esql.VerificationException;
import org.elasticsearch.xpack.esql.action.EsqlQueryRequest;
import org.elasticsearch.xpack.esql.action.EsqlResolveFieldsAction;
Expand All @@ -43,16 +50,19 @@
import org.elasticsearch.xpack.esql.datasources.spi.DataSourcePlugin;
import org.elasticsearch.xpack.esql.enrich.EnrichPolicyResolver;
import org.elasticsearch.xpack.esql.execution.PlanExecutor;
import org.elasticsearch.xpack.esql.inference.InferenceService;
import org.elasticsearch.xpack.esql.inference.InferenceSettings;
import org.elasticsearch.xpack.esql.parser.ParsingException;
import org.elasticsearch.xpack.esql.planner.PlannerSettings;
import org.elasticsearch.xpack.esql.planner.PlannerUtils;
import org.elasticsearch.xpack.esql.plugin.EsqlPlugin;
import org.elasticsearch.xpack.esql.plugin.TransportActionServices;
import org.elasticsearch.xpack.esql.querylog.EsqlQueryLog;
import org.elasticsearch.xpack.esql.session.EsqlSession;
import org.elasticsearch.xpack.esql.session.IndexResolver;
import org.elasticsearch.xpack.esql.session.Result;
import org.elasticsearch.xpack.esql.session.Versioned;
import org.elasticsearch.xpack.esql.view.InMemoryViewService;
import org.junit.After;
import org.junit.Before;
import org.mockito.stubbing.Answer;

import java.util.ArrayList;
Expand All @@ -61,6 +71,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static org.elasticsearch.xpack.esql.EsqlTestUtils.TEST_FUNCTION_REGISTRY;
import static org.elasticsearch.xpack.esql.EsqlTestUtils.TEST_PARSER;
Expand All @@ -70,23 +81,59 @@
import static org.elasticsearch.xpack.esql.querylog.EsqlQueryLogTests.mockLogFieldProvider;
import static org.hamcrest.Matchers.instanceOf;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class PlanExecutorMetricsTests extends ESTestCase {

private ThreadPool threadPool;
private static final TransportActionServices MOCK_TRANSPORT_ACTION_SERVICES = createTransportActionServices();

private static TransportActionServices createTransportActionServices() {
ClusterService clusterService = createMockClusterService();
return new TransportActionServices(
createMockTransportService(),
mock(SearchService.class),
null,
clusterService,
mock(ProjectResolver.class),
mock(IndexNameExpressionResolver.class),
null,
new InferenceService(mock(Client.class), clusterService),
UserAgentParserRegistry.NOOP,
new BlockFactoryProvider(PlannerUtils.NON_BREAKING_BLOCK_FACTORY),
new PlannerSettings.Holder(clusterService),
CrossProjectModeDecider.NOOP
);
}

private static ClusterService createMockClusterService() {
var service = mock(ClusterService.class);
doReturn(new ClusterName("test-cluster")).when(service).getClusterName();
doReturn(Settings.EMPTY).when(service).getSettings();

// Create ClusterSettings with the required inference settings
Set<Setting<?>> settings = new HashSet<>();
settings.addAll(InferenceSettings.getSettings());
settings.addAll(PlannerSettings.settings());
var clusterSettings = new ClusterSettings(Settings.EMPTY, settings);
doReturn(clusterSettings).when(service).getClusterSettings();
return service;
}

@Before
public void setUpThreadPool() throws Exception {
threadPool = new TestThreadPool(PlanExecutorMetricsTests.class.getSimpleName());
private static TransportService createMockTransportService() {
var service = mock(TransportService.class);
doReturn(createMockThreadPool()).when(service).getThreadPool();
return service;
}

@After
public void shutdownThreadPool() throws Exception {
terminate(threadPool);
private static ThreadPool createMockThreadPool() {
var threadPool = mock(ThreadPool.class);
doReturn(EsExecutors.DIRECT_EXECUTOR_SERVICE).when(threadPool).executor(anyString());
return threadPool;
}

@SuppressWarnings("unchecked")
Expand Down Expand Up @@ -179,7 +226,7 @@ public void testFailedMetric() throws Exception {
createEsqlExecutionInfo(randomBoolean()),
groupIndicesByCluster,
runPhase,
EsqlTestUtils.MOCK_TRANSPORT_ACTION_SERVICES,
MOCK_TRANSPORT_ACTION_SERVICES,
new ActionListener<>() {
@Override
public void onResponse(Versioned<Result> result) {
Expand Down Expand Up @@ -213,7 +260,7 @@ public void onFailure(Exception e) {
createEsqlExecutionInfo(randomBoolean()),
groupIndicesByCluster,
runPhase,
EsqlTestUtils.MOCK_TRANSPORT_ACTION_SERVICES,
MOCK_TRANSPORT_ACTION_SERVICES,
new ActionListener<>() {
@Override
public void onResponse(Versioned<Result> result) {}
Expand Down Expand Up @@ -530,7 +577,7 @@ private void executeEsql(
createEsqlExecutionInfo(randomBoolean()),
groupIndicesByCluster,
runPhase,
EsqlTestUtils.MOCK_TRANSPORT_ACTION_SERVICES,
MOCK_TRANSPORT_ACTION_SERVICES,
listener
);
}
Expand Down
Loading