diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/categorize.json b/docs/reference/query-languages/esql/kibana/definition/functions/categorize.json index 088384a3fa1a..4f6e1379275e 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/categorize.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/categorize.json @@ -2,6 +2,7 @@ "comment" : "This is generated by ESQL’s AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it.", "type" : "grouping", "name" : "categorize", + "license" : "PLATINUM", "description" : "Groups text messages into categories of similarly formatted text values.", "signatures" : [ { @@ -13,6 +14,7 @@ "description" : "Expression to categorize" } ], + "license" : "PLATINUM", "variadic" : false, "returnType" : "keyword" }, @@ -25,6 +27,7 @@ "description" : "Expression to categorize" } ], + "license" : "PLATINUM", "variadic" : false, "returnType" : "keyword" } diff --git a/docs/reference/query-languages/esql/kibana/definition/functions/st_extent_agg.json b/docs/reference/query-languages/esql/kibana/definition/functions/st_extent_agg.json index fa129eec29da..9c05870b2cfd 100644 --- a/docs/reference/query-languages/esql/kibana/definition/functions/st_extent_agg.json +++ b/docs/reference/query-languages/esql/kibana/definition/functions/st_extent_agg.json @@ -25,6 +25,7 @@ "description" : "" } ], + "license" : "PLATINUM", "variadic" : false, "returnType" : "cartesian_shape" }, @@ -49,6 +50,7 @@ "description" : "" } ], + "license" : "PLATINUM", "variadic" : false, "returnType" : "geo_shape" } diff --git a/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/type/DataType.java b/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/type/DataType.java index 3de94bb90e5e..a330ac076d2c 100644 --- a/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/type/DataType.java +++ b/x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/type/DataType.java @@ -560,6 +560,10 @@ public enum DataType { return t == GEO_POINT || t == CARTESIAN_POINT; } + public static boolean isSpatialShape(DataType t) { + return t == GEO_SHAPE || t == CARTESIAN_SHAPE; + } + public static boolean isSpatialGeo(DataType t) { return t == GEO_POINT || t == GEO_SHAPE; } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/AbstractFunctionTestCase.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/AbstractFunctionTestCase.java index e220eac5ab7a..f66133d10a8e 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/AbstractFunctionTestCase.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/AbstractFunctionTestCase.java @@ -26,9 +26,13 @@ import org.elasticsearch.compute.operator.EvalOperator.ExpressionEvaluator; import org.elasticsearch.compute.test.BlockTestUtils; import org.elasticsearch.compute.test.TestBlockFactory; import org.elasticsearch.indices.CrankyCircuitBreakerService; +import org.elasticsearch.license.License; +import org.elasticsearch.license.XPackLicenseState; +import org.elasticsearch.license.internal.XPackLicenseStatus; import org.elasticsearch.logging.LogManager; import org.elasticsearch.logging.Logger; import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.xpack.esql.LicenseAware; import org.elasticsearch.xpack.esql.core.expression.Attribute; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.expression.FieldAttribute; @@ -54,7 +58,6 @@ import org.hamcrest.Matchers; import org.junit.After; import org.junit.AfterClass; -import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -730,7 +733,8 @@ public abstract class AbstractFunctionTestCase extends ESTestCase { */ @AfterClass public static void testFunctionInfo() { - Logger log = LogManager.getLogger(getTestClass()); + Class testClass = getTestClass(); + Logger log = LogManager.getLogger(testClass); FunctionDefinition definition = definition(functionName()); if (definition == null) { log.info("Skipping function info checks because the function isn't registered"); @@ -753,7 +757,7 @@ public abstract class AbstractFunctionTestCase extends ESTestCase { for (int i = 0; i < args.size(); i++) { typesFromSignature.add(new HashSet<>()); } - for (Map.Entry, DataType> entry : signatures(getTestClass()).entrySet()) { + for (Map.Entry, DataType> entry : signatures(testClass).entrySet()) { List types = entry.getKey(); for (int i = 0; i < args.size() && i < types.size(); i++) { typesFromSignature.get(i).add(types.get(i).esNameIfPossible()); @@ -796,6 +800,101 @@ public abstract class AbstractFunctionTestCase extends ESTestCase { assertEquals(returnFromSignature, returnTypes); } + /** + * This test is meant to validate that the license checks documented match those enforced. + * The expectations are set in the test class using a method with this signature: + * + * public static License.OperationMode licenseRequirement(List<DataType> fieldTypes); + * + * License enforcement in the function class is achieved using the interface LicenseAware. + * This test will make sure the two are in agreement, and does not require that the function class actually + * report its license level. If we add license checks to any function, but fail to also add the expected + * license level to the test class, this test will fail. + */ + @AfterClass + public static void testFunctionLicenseChecks() throws Exception { + Class testClass = getTestClass(); + Logger log = LogManager.getLogger(testClass); + FunctionDefinition definition = definition(functionName()); + if (definition == null) { + log.info("Skipping function info checks because the function isn't registered"); + return; + } + log.info("Running function license checks"); + DocsV3Support.LicenseRequirementChecker licenseChecker = new DocsV3Support.LicenseRequirementChecker(testClass); + License.OperationMode functionLicense = licenseChecker.invoke(null); + Constructor ctor = constructorWithFunctionInfo(definition.clazz()); + if (LicenseAware.class.isAssignableFrom(definition.clazz()) == false) { + // Perform simpler no-signature tests + assertThat( + "Function " + definition.name() + " should be licensed under " + functionLicense, + functionLicense, + equalTo(License.OperationMode.BASIC) + ); + return; + } + // For classes with LicenseAware, we need to check that the license is correct + TestCheckLicense checkLicense = new TestCheckLicense(); + + // Go through all signatures and assert that the license is as expected + signatures(testClass).forEach((signature, returnType) -> { + try { + License.OperationMode license = licenseChecker.invoke(signature); + assertNotNull("License should not be null", license); + + // Construct an instance of the class and then call it's licenseCheck method, and compare the results + Object[] args = new Object[signature.size() + 1]; + args[0] = Source.EMPTY; + for (int i = 0; i < signature.size(); i++) { + args[i + 1] = new Literal(Source.EMPTY, null, signature.get(i)); + } + Object instance = ctor.newInstance(args); + // Check that object implements the LicenseAware interface + if (LicenseAware.class.isAssignableFrom(instance.getClass())) { + LicenseAware licenseAware = (LicenseAware) instance; + switch (license) { + case BASIC -> checkLicense.assertLicenseCheck(licenseAware, signature, true, true, true); + case PLATINUM -> checkLicense.assertLicenseCheck(licenseAware, signature, false, true, true); + case ENTERPRISE -> checkLicense.assertLicenseCheck(licenseAware, signature, false, false, true); + } + } else { + fail("Function " + definition.name() + " does not implement LicenseAware"); + } + } catch (Exception e) { + fail(e); + } + }); + } + + private static class TestCheckLicense { + XPackLicenseState basicLicense = makeLicenseState(License.OperationMode.BASIC); + XPackLicenseState platinumLicense = makeLicenseState(License.OperationMode.PLATINUM); + XPackLicenseState enterpriseLicense = makeLicenseState(License.OperationMode.ENTERPRISE); + + private void assertLicenseCheck( + LicenseAware licenseAware, + List signature, + boolean allowsBasic, + boolean allowsPlatinum, + boolean allowsEnterprise + ) { + boolean basic = licenseAware.licenseCheck(basicLicense); + boolean platinum = licenseAware.licenseCheck(platinumLicense); + boolean enterprise = licenseAware.licenseCheck(enterpriseLicense); + assertThat("Basic license should be accepted for " + signature, basic, equalTo(allowsBasic)); + assertThat("Platinum license should be accepted for " + signature, platinum, equalTo(allowsPlatinum)); + assertThat("Enterprise license should be accepted for " + signature, enterprise, equalTo(allowsEnterprise)); + } + + private void assertLicenseCheck(List signature, boolean allowed, boolean expected) { + assertThat("Basic license should " + (expected ? "" : "not ") + "be accepted for " + signature, allowed, equalTo(expected)); + } + } + + private static XPackLicenseState makeLicenseState(License.OperationMode mode) { + return new XPackLicenseState(System::currentTimeMillis, new XPackLicenseStatus(mode, true, "")); + } + /** * Asserts the result of a test case matches the expected result and warnings. *

@@ -865,7 +964,7 @@ public abstract class AbstractFunctionTestCase extends ESTestCase { } @AfterClass - public static void renderDocs() throws IOException { + public static void renderDocs() throws Exception { if (System.getProperty("generateDocs") == null) { return; } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/DocsV3Support.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/DocsV3Support.java index 44624fd75cd7..8f15dc5b7d9d 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/DocsV3Support.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/DocsV3Support.java @@ -11,6 +11,7 @@ import com.unboundid.util.NotNull; import org.elasticsearch.common.Strings; import org.elasticsearch.core.PathUtils; +import org.elasticsearch.license.License; import org.elasticsearch.logging.LogManager; import org.elasticsearch.logging.Logger; import org.elasticsearch.xcontent.XContentBuilder; @@ -46,6 +47,7 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; +import java.lang.reflect.Method; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; @@ -107,7 +109,7 @@ public abstract class DocsV3Support { return new OperatorsDocsSupport(name, testClass); } - static void renderDocs(String name, Class testClass) throws IOException { + static void renderDocs(String name, Class testClass) throws Exception { if (OPERATORS.containsKey(name)) { var docs = DocsV3Support.forOperators(name, testClass); docs.renderSignature(); @@ -126,7 +128,7 @@ public abstract class DocsV3Support { String name, Function description, Class testClass - ) throws IOException { + ) throws Exception { var docs = forOperators("not " + name.toLowerCase(Locale.ROOT), testClass); docs.renderDocsForNegatedOperators(ctor, description); } @@ -272,12 +274,46 @@ public abstract class DocsV3Support { } } + /** + * This class is used to check if a license requirement method exists in the test class. + * This is used to add license requirement information to the generated documentation. + */ + public static class LicenseRequirementChecker { + private Method staticMethod; + private Function, License.OperationMode> fallbackLambda; + + public LicenseRequirementChecker(Class testClass) { + try { + staticMethod = testClass.getMethod("licenseRequirement", List.class); + if (License.OperationMode.class.equals(staticMethod.getReturnType()) == false + || java.lang.reflect.Modifier.isStatic(staticMethod.getModifiers()) == false) { + staticMethod = null; // Reset if the method doesn't match the signature + } + } catch (NoSuchMethodException e) { + staticMethod = null; + } + + if (staticMethod == null) { + fallbackLambda = fieldTypes -> License.OperationMode.BASIC; + } + } + + public License.OperationMode invoke(List fieldTypes) throws Exception { + if (staticMethod != null) { + return (License.OperationMode) staticMethod.invoke(null, fieldTypes); + } else { + return fallbackLambda.apply(fieldTypes); + } + } + } + protected final String category; protected final String name; protected final FunctionDefinition definition; protected final Logger logger; private final Supplier, DataType>> signatures; private TempFileWriter tempFileWriter; + private final LicenseRequirementChecker licenseChecker; protected DocsV3Support(String category, String name, Class testClass, Supplier, DataType>> signatures) { this(category, name, null, testClass, signatures); @@ -296,6 +332,7 @@ public abstract class DocsV3Support { this.logger = LogManager.getLogger(testClass); this.signatures = signatures; this.tempFileWriter = new DocsFileWriter(); + this.licenseChecker = new LicenseRequirementChecker(testClass); } /** Used in tests to capture output for asserting on the content */ @@ -460,7 +497,7 @@ public abstract class DocsV3Support { protected abstract void renderSignature() throws IOException; - protected abstract void renderDocs() throws IOException; + protected abstract void renderDocs() throws Exception; static class FunctionDocsSupport extends DocsV3Support { private FunctionDocsSupport(String name, Class testClass) { @@ -488,7 +525,7 @@ public abstract class DocsV3Support { } @Override - protected void renderDocs() throws IOException { + protected void renderDocs() throws Exception { if (definition == null) { logger.info("Skipping rendering docs because the function '{}' isn't registered", name); } else { @@ -497,7 +534,7 @@ public abstract class DocsV3Support { } } - private void renderDocs(FunctionDefinition definition) throws IOException { + private void renderDocs(FunctionDefinition definition) throws Exception { EsqlFunctionRegistry.FunctionDescription description = EsqlFunctionRegistry.description(definition); if (name.equals("case")) { /* @@ -711,7 +748,7 @@ public abstract class DocsV3Support { } @Override - public void renderDocs() throws IOException { + public void renderDocs() throws Exception { Constructor ctor = constructorWithFunctionInfo(op.clazz()); if (ctor != null) { FunctionInfo functionInfo = ctor.getAnnotation(FunctionInfo.class); @@ -722,7 +759,7 @@ public abstract class DocsV3Support { } } - void renderDocsForNegatedOperators(Constructor ctor, Function description) throws IOException { + void renderDocsForNegatedOperators(Constructor ctor, Function description) throws Exception { String baseName = name.toLowerCase(Locale.ROOT).replace("not ", ""); OperatorConfig op = OPERATORS.get(baseName); assert op != null; @@ -795,7 +832,7 @@ public abstract class DocsV3Support { } void renderDocsForOperators(String name, String titleName, Constructor ctor, FunctionInfo info, boolean variadic) - throws IOException { + throws Exception { renderKibanaInlineDocs(name, titleName, info); var params = ctor.getParameters(); @@ -999,7 +1036,7 @@ public abstract class DocsV3Support { FunctionInfo info, List args, boolean variadic - ) throws IOException { + ) throws Exception { try (XContentBuilder builder = JsonXContent.contentBuilder().prettyPrint().lfAtEnd().startObject()) { builder.field( @@ -1019,6 +1056,10 @@ public abstract class DocsV3Support { }); } builder.field("name", name); + License.OperationMode license = licenseChecker.invoke(null); + if (license != null && license != License.OperationMode.BASIC) { + builder.field("license", license.toString()); + } if (titleName != null && titleName.equals(name) == false) { builder.field("titleName", titleName); } @@ -1073,6 +1114,10 @@ public abstract class DocsV3Support { builder.endObject(); } builder.endArray(); + license = licenseChecker.invoke(sig.getKey()); + if (license != null && license != License.OperationMode.BASIC) { + builder.field("license", license.toString()); + } builder.field("variadic", variadic); builder.field("returnType", sig.getValue().esNameIfPossible()); builder.endObject(); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/DocsV3SupportTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/DocsV3SupportTests.java index 275849b9bb0f..86fe852ab900 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/DocsV3SupportTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/DocsV3SupportTests.java @@ -228,7 +228,7 @@ public class DocsV3SupportTests extends ESTestCase { assertThat(results, equalTo(expectedResults)); } - public void testRenderingExampleFromClass() throws IOException { + public void testRenderingExampleFromClass() throws Exception { String expected = """ % This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. @@ -306,7 +306,7 @@ public class DocsV3SupportTests extends ESTestCase { assertThat(rendered.trim(), equalTo(expected.trim())); } - public void testRenderingLayoutFromClass() throws IOException { + public void testRenderingLayoutFromClass() throws Exception { String expected = """ % This is generated by ESQL's AbstractFunctionTestCase. Do no edit it. See ../README.md for how to regenerate it. @@ -353,7 +353,7 @@ public class DocsV3SupportTests extends ESTestCase { assertThat(rendered.trim(), equalTo(expected.trim())); } - private TestDocsFileWriter renderTestClassDocs() throws IOException { + private TestDocsFileWriter renderTestClassDocs() throws Exception { FunctionInfo info = functionInfo(TestClass.class); assert info != null; FunctionDefinition definition = EsqlFunctionRegistry.def(TestClass.class, TestClass::new, "count"); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/SpatialAggregationTestCase.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/SpatialAggregationTestCase.java new file mode 100644 index 000000000000..3ac6179cd1a3 --- /dev/null +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/SpatialAggregationTestCase.java @@ -0,0 +1,36 @@ +/* + * 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.expression.function.aggregate; + +import org.elasticsearch.license.License; +import org.elasticsearch.xpack.esql.core.type.DataType; +import org.elasticsearch.xpack.esql.expression.function.AbstractAggregationTestCase; + +import java.util.List; + +public abstract class SpatialAggregationTestCase extends AbstractAggregationTestCase { + + /** + * All spatial aggregations have the same licensing requirements, which is that the function itself is not licensed, but + * the field types are. Aggregations over shapes are licensed under platinum, while aggregations over points are licensed under basic. + * @param fieldTypes (null for the function itself, otherwise a map of field named to types) + * @return The license requirement for the function with that type signature + */ + protected static License.OperationMode licenseRequirement(List fieldTypes) { + if (fieldTypes == null || fieldTypes.isEmpty()) { + // The function itself is not licensed, but the field types are. + return License.OperationMode.BASIC; + } + if (fieldTypes.stream().anyMatch(DataType::isSpatialShape)) { + // Only aggregations over shapes are licensed under platinum. + return License.OperationMode.PLATINUM; + } + // All other field types are licensed under basic. + return License.OperationMode.BASIC; + } +} diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/SpatialCentroidTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/SpatialCentroidTests.java index a99cb8f60e3f..25bb6e242cf8 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/SpatialCentroidTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/SpatialCentroidTests.java @@ -14,6 +14,7 @@ import org.apache.lucene.util.BytesRef; import org.elasticsearch.geometry.Point; import org.elasticsearch.geometry.utils.GeometryValidator; import org.elasticsearch.geometry.utils.WellKnownBinary; +import org.elasticsearch.license.License; import org.elasticsearch.search.aggregations.metrics.CompensatedSum; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.tree.Source; @@ -39,6 +40,10 @@ public class SpatialCentroidTests extends AbstractAggregationTestCase { this.testCase = testCaseSupplier.get(); } + public static License.OperationMode licenseRequirement(List fieldTypes) { + return SpatialAggregationTestCase.licenseRequirement(fieldTypes); + } + @ParametersFactory public static Iterable parameters() { var suppliers = Stream.of( diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/SpatialExtentTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/SpatialExtentTests.java index 9a0a62ce2d06..a73a00741e3c 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/SpatialExtentTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/aggregate/SpatialExtentTests.java @@ -17,12 +17,12 @@ import org.elasticsearch.geometry.utils.GeometryValidator; import org.elasticsearch.geometry.utils.SpatialEnvelopeVisitor; import org.elasticsearch.geometry.utils.SpatialEnvelopeVisitor.WrapLongitude; import org.elasticsearch.geometry.utils.WellKnownBinary; +import org.elasticsearch.license.License; import org.elasticsearch.test.hamcrest.RectangleMatcher; import org.elasticsearch.test.hamcrest.WellKnownBinaryBytesRefMatcher; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.tree.Source; import org.elasticsearch.xpack.esql.core.type.DataType; -import org.elasticsearch.xpack.esql.expression.function.AbstractAggregationTestCase; import org.elasticsearch.xpack.esql.expression.function.FunctionName; import org.elasticsearch.xpack.esql.expression.function.MultiRowTestCaseSupplier; import org.elasticsearch.xpack.esql.expression.function.MultiRowTestCaseSupplier.IncludingAltitude; @@ -33,11 +33,15 @@ import java.util.function.Supplier; import java.util.stream.Stream; @FunctionName("st_extent_agg") -public class SpatialExtentTests extends AbstractAggregationTestCase { +public class SpatialExtentTests extends SpatialAggregationTestCase { public SpatialExtentTests(@Name("TestCase") Supplier testCaseSupplier) { this.testCase = testCaseSupplier.get(); } + public static License.OperationMode licenseRequirement(List fieldTypes) { + return SpatialAggregationTestCase.licenseRequirement(fieldTypes); + } + @ParametersFactory public static Iterable parameters() { var suppliers = Stream.of( diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/grouping/CategorizeTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/grouping/CategorizeTests.java index dfdfd82d08af..f69bb7eb3e7b 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/grouping/CategorizeTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/grouping/CategorizeTests.java @@ -11,6 +11,7 @@ import com.carrotsearch.randomizedtesting.annotations.Name; import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; import org.apache.lucene.util.BytesRef; +import org.elasticsearch.license.License; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.tree.Source; import org.elasticsearch.xpack.esql.core.type.DataType; @@ -34,6 +35,10 @@ public class CategorizeTests extends AbstractScalarFunctionTestCase { this.testCase = testCaseSupplier.get(); } + public static License.OperationMode licenseRequirement(List fieldTypes) { + return License.OperationMode.PLATINUM; + } + @ParametersFactory public static Iterable parameters() { List suppliers = new ArrayList<>(); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/RLikeTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/RLikeTests.java index 5578b2bfb191..c2397f0340e6 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/RLikeTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/RLikeTests.java @@ -22,7 +22,6 @@ import org.elasticsearch.xpack.esql.expression.function.AbstractScalarFunctionTe import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier; import org.junit.AfterClass; -import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.function.Function; @@ -155,7 +154,7 @@ public class RLikeTests extends AbstractScalarFunctionTestCase { } @AfterClass - public static void renderNotRLike() throws IOException { + public static void renderNotRLike() throws Exception { renderNegatedOperator(constructorWithFunctionInfo(RLike.class), "RLIKE", d -> d, getTestClass()); } } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/WildcardLikeTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/WildcardLikeTests.java index 3bf14fb8c347..bb59f9e501ef 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/WildcardLikeTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/string/WildcardLikeTests.java @@ -22,7 +22,6 @@ import org.elasticsearch.xpack.esql.expression.function.FunctionName; import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier; import org.junit.AfterClass; -import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.function.Supplier; @@ -92,7 +91,7 @@ public class WildcardLikeTests extends AbstractScalarFunctionTestCase { } @AfterClass - public static void renderNotLike() throws IOException { + public static void renderNotLike() throws Exception { renderNegatedOperator(constructorWithFunctionInfo(WildcardLike.class), "LIKE", d -> d, getTestClass()); } } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/CastOperatorTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/CastOperatorTests.java index c1f5b9faed8e..ff1f1f69a659 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/CastOperatorTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/CastOperatorTests.java @@ -16,7 +16,6 @@ import org.elasticsearch.xpack.esql.expression.function.FunctionInfo; import org.elasticsearch.xpack.esql.expression.function.Param; import org.junit.AfterClass; -import java.io.IOException; import java.util.List; import java.util.Map; @@ -26,7 +25,7 @@ public class CastOperatorTests extends ESTestCase { } @AfterClass - public static void renderDocs() throws IOException { + public static void renderDocs() throws Exception { if (System.getProperty("generateDocs") == null) { return; } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/NullPredicatesTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/NullPredicatesTests.java index 7af61532fed4..69bfcc99a21e 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/NullPredicatesTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/NullPredicatesTests.java @@ -18,7 +18,6 @@ import org.elasticsearch.xpack.esql.expression.function.Param; import org.elasticsearch.xpack.esql.expression.function.scalar.convert.ToStringTests; import org.junit.AfterClass; -import java.io.IOException; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -32,7 +31,7 @@ public class NullPredicatesTests extends ESTestCase { } @AfterClass - public static void renderDocs() throws IOException { + public static void renderDocs() throws Exception { if (System.getProperty("generateDocs") == null) { return; } @@ -62,7 +61,7 @@ public class NullPredicatesTests extends ESTestCase { ); } - private static void renderNullPredicate(DocsV3Support.OperatorConfig op) throws IOException { + private static void renderNullPredicate(DocsV3Support.OperatorConfig op) throws Exception { var docs = new DocsV3Support.OperatorsDocsSupport(op.name(), NullPredicatesTests.class, op, NullPredicatesTests::signatures); docs.renderSignature(); docs.renderDocs(); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/InTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/InTests.java index aed08b32bb6d..449389accc37 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/InTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/InTests.java @@ -26,7 +26,6 @@ import org.elasticsearch.xpack.esql.optimizer.rules.physical.local.LucenePushdow import org.elasticsearch.xpack.esql.planner.TranslatorHandler; import org.junit.AfterClass; -import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -319,7 +318,7 @@ public class InTests extends AbstractFunctionTestCase { } @AfterClass - public static void renderNotIn() throws IOException { + public static void renderNotIn() throws Exception { renderNegatedOperator( constructorWithFunctionInfo(In.class), "IN",