Browse Source

support inject/remove warnings and inject allowed_warnings (#69010)

This commit adds ability to inject warnings, allowed_warnings, or 
remove warnings during the transform of compatible tests.

This is useful to allow for new sets of warnings or allowed_warnings
when running REST compatible testing. The following is an example of
how one could configure these transformations.   

```
tasks.named("transformV7RestTests").configure({ task ->
        task.addWarning("one", "warning1", "warning2")
        task.addAllowedWarning("added allowed warning")
        task.removeWarning("one", "warning to remove")
      })
```
Jake Landis 4 years ago
parent
commit
023278253e
17 changed files with 660 additions and 3 deletions
  1. 27 3
      buildSrc/src/integTest/groovy/org/elasticsearch/gradle/YamlRestCompatTestPluginFuncTest.groovy
  2. 30 0
      buildSrc/src/main/java/org/elasticsearch/gradle/internal/rest/compat/RestCompatTestTransformTask.java
  3. 1 0
      buildSrc/src/main/java/org/elasticsearch/gradle/test/rest/transform/headers/InjectHeaders.java
  4. 2 0
      buildSrc/src/main/java/org/elasticsearch/gradle/test/rest/transform/match/AddMatch.java
  5. 2 0
      buildSrc/src/main/java/org/elasticsearch/gradle/test/rest/transform/match/RemoveMatch.java
  6. 2 0
      buildSrc/src/main/java/org/elasticsearch/gradle/test/rest/transform/match/ReplaceMatch.java
  7. 64 0
      buildSrc/src/main/java/org/elasticsearch/gradle/test/rest/transform/warnings/InjectAllowedWarnings.java
  8. 79 0
      buildSrc/src/main/java/org/elasticsearch/gradle/test/rest/transform/warnings/InjectWarnings.java
  9. 69 0
      buildSrc/src/main/java/org/elasticsearch/gradle/test/rest/transform/warnings/RemoveWarnings.java
  10. 86 0
      buildSrc/src/test/java/org/elasticsearch/gradle/test/rest/transform/TransformTests.java
  11. 70 0
      buildSrc/src/test/java/org/elasticsearch/gradle/test/rest/transform/warnings/InjectAllowedWarningsTests.java
  12. 87 0
      buildSrc/src/test/java/org/elasticsearch/gradle/test/rest/transform/warnings/InjectWarningsTests.java
  13. 78 0
      buildSrc/src/test/java/org/elasticsearch/gradle/test/rest/transform/warnings/RemoveWarningsTests.java
  14. 14 0
      buildSrc/src/test/resources/rest/transform/warnings/with_existing_allowed_warnings.yml
  15. 13 0
      buildSrc/src/test/resources/rest/transform/warnings/with_existing_single_warnings.yml
  16. 23 0
      buildSrc/src/test/resources/rest/transform/warnings/with_existing_warnings.yml
  17. 13 0
      buildSrc/src/test/resources/rest/transform/warnings/without_existing_warnings.yml

+ 27 - 3
buildSrc/src/integTest/groovy/org/elasticsearch/gradle/YamlRestCompatTestPluginFuncTest.groovy

@@ -11,6 +11,7 @@ package org.elasticsearch.gradle
 import com.fasterxml.jackson.databind.ObjectMapper
 import com.fasterxml.jackson.databind.ObjectReader
 import com.fasterxml.jackson.databind.ObjectWriter
+import com.fasterxml.jackson.databind.SequenceWriter
 import com.fasterxml.jackson.databind.node.ObjectNode
 import com.fasterxml.jackson.dataformat.yaml.YAMLFactory
 import org.elasticsearch.gradle.fixtures.AbstractRestResourcesFuncTest
@@ -209,6 +210,9 @@ class YamlRestCompatTestPluginFuncTest extends AbstractRestResourcesFuncTest {
               task.removeMatch("_source.blah")
               task.removeMatch("_source.junk", "two")
               task.addMatch("_source.added", [name: 'jake', likes: 'cheese'], "one")
+              task.addWarning("one", "warning1", "warning2")
+              task.addAllowedWarning("added allowed warning")
+              task.removeWarning("one", "warning to remove")
             })
             // can't actually spin up test cluster from this test
            tasks.withType(Test).configureEach{ enabled = false }
@@ -222,6 +226,8 @@ class YamlRestCompatTestPluginFuncTest extends AbstractRestResourcesFuncTest {
               get:
                 index: test
                 id: 1
+              warnings:
+                - "warning to remove"
           - match: { _source.values: ["foo"] }
           - match: { _type: "_foo" }
           - match: { _source.blah: 1234 }
@@ -253,16 +259,24 @@ class YamlRestCompatTestPluginFuncTest extends AbstractRestResourcesFuncTest {
         ---
         setup:
         - skip:
-            features: "headers"
+            features:
+            - "headers"
+            - "warnings"
+            - "allowed_warnings"
         ---
         one:
         - do:
             get:
               index: "test"
               id: 1
+            warnings:
+            - "warning1"
+            - "warning2"
             headers:
-              Content-Type: "application/vnd.elasticsearch+json;compatible-with=7"
               Accept: "application/vnd.elasticsearch+json;compatible-with=7"
+              Content-Type: "application/vnd.elasticsearch+json;compatible-with=7"
+            allowed_warnings:
+            - "added allowed warning"
         - match:
             _source.values:
             - "z"
@@ -284,8 +298,10 @@ class YamlRestCompatTestPluginFuncTest extends AbstractRestResourcesFuncTest {
               index: "test"
               id: 1
             headers:
-              Content-Type: "application/vnd.elasticsearch+json;compatible-with=7"
               Accept: "application/vnd.elasticsearch+json;compatible-with=7"
+              Content-Type: "application/vnd.elasticsearch+json;compatible-with=7"
+            allowed_warnings:
+            - "added allowed warning"
         - match:
             _source.values:
             - "foo"
@@ -296,6 +312,14 @@ class YamlRestCompatTestPluginFuncTest extends AbstractRestResourcesFuncTest {
         """.stripIndent()).readAll()
 
         expectedAll.eachWithIndex{ ObjectNode expected, int i ->
+            if(expected != actual.get(i)) {
+                println("\nTransformed Test:")
+                SequenceWriter sequenceWriter = WRITER.writeValues(System.out)
+                for (ObjectNode transformedTest : actual) {
+                    sequenceWriter.write(transformedTest)
+                }
+                sequenceWriter.close()
+            }
            assert expected == actual.get(i)
         }
 

+ 30 - 0
buildSrc/src/main/java/org/elasticsearch/gradle/internal/rest/compat/RestCompatTestTransformTask.java

@@ -24,6 +24,9 @@ import org.elasticsearch.gradle.test.rest.transform.headers.InjectHeaders;
 import org.elasticsearch.gradle.test.rest.transform.match.AddMatch;
 import org.elasticsearch.gradle.test.rest.transform.match.RemoveMatch;
 import org.elasticsearch.gradle.test.rest.transform.match.ReplaceMatch;
+import org.elasticsearch.gradle.test.rest.transform.warnings.InjectAllowedWarnings;
+import org.elasticsearch.gradle.test.rest.transform.warnings.InjectWarnings;
+import org.elasticsearch.gradle.test.rest.transform.warnings.RemoveWarnings;
 import org.gradle.api.DefaultTask;
 import org.gradle.api.file.DirectoryProperty;
 import org.gradle.api.file.FileTree;
@@ -42,10 +45,12 @@ import javax.inject.Inject;
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * A task to transform REST tests for use in REST API compatibility before they are executed.
@@ -134,6 +139,31 @@ public class RestCompatTestTransformTask extends DefaultTask {
         transformations.add(new AddMatch(subKey, MAPPER.convertValue(value, JsonNode.class), testName));
     }
 
+    /**
+     * Adds one or more warnings to the given test
+     * @param testName the test name to add the warning
+     * @param warnings the warning(s) to add
+     */
+    public void addWarning(String testName, String... warnings) {
+        transformations.add(new InjectWarnings(Arrays.asList(warnings), testName));
+    }
+
+    /**
+     * Removes one or more warnings
+     * @param warnings the warning(s) to remove
+     */
+    public void removeWarning(String... warnings) {
+        transformations.add(new RemoveWarnings(Set.copyOf(Arrays.asList(warnings))));
+    }
+
+    /**
+     * Adds one or more allowed warnings
+     * @param allowedWarnings the warning(s) to add
+     */
+    public void addAllowedWarning(String... allowedWarnings) {
+        transformations.add(new InjectAllowedWarnings(Arrays.asList(allowedWarnings)));
+    }
+
     @OutputDirectory
     public DirectoryProperty getOutputDirectory() {
         return outputDirectory;

+ 1 - 0
buildSrc/src/main/java/org/elasticsearch/gradle/test/rest/transform/headers/InjectHeaders.java

@@ -56,6 +56,7 @@ public class InjectHeaders extends FeatureInjector implements RestTestTransformB
     }
 
     @Override
+    @Internal
     public String getSkipFeatureName() {
         return "headers";
     }

+ 2 - 0
buildSrc/src/main/java/org/elasticsearch/gradle/test/rest/transform/match/AddMatch.java

@@ -15,6 +15,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
 import org.elasticsearch.gradle.test.rest.transform.RestTestContext;
 import org.elasticsearch.gradle.test.rest.transform.RestTestTransformByParentArray;
 import org.gradle.api.tasks.Input;
+import org.gradle.api.tasks.Internal;
 
 import java.util.Objects;
 
@@ -48,6 +49,7 @@ public class AddMatch implements RestTestTransformByParentArray {
     }
 
     @Override
+    @Internal
     public String getKeyOfArrayToFind() {
         // match objects are always in the array that is the direct child of the test name, i.e.
         // "my test name" : [ {"do" : ... }, { "match" : .... }]

+ 2 - 0
buildSrc/src/main/java/org/elasticsearch/gradle/test/rest/transform/match/RemoveMatch.java

@@ -12,6 +12,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
 import org.elasticsearch.gradle.test.rest.transform.RestTestContext;
 import org.elasticsearch.gradle.test.rest.transform.RestTestTransformByParentObject;
 import org.gradle.api.tasks.Input;
+import org.gradle.api.tasks.Internal;
 import org.gradle.api.tasks.Optional;
 
 /**
@@ -33,6 +34,7 @@ public class RemoveMatch implements RestTestTransformByParentObject {
     }
 
     @Override
+    @Internal
     public String getKeyToFind() {
         return "match";
     }

+ 2 - 0
buildSrc/src/main/java/org/elasticsearch/gradle/test/rest/transform/match/ReplaceMatch.java

@@ -13,6 +13,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
 import org.elasticsearch.gradle.test.rest.transform.RestTestContext;
 import org.elasticsearch.gradle.test.rest.transform.RestTestTransformByParentObject;
 import org.gradle.api.tasks.Input;
+import org.gradle.api.tasks.Internal;
 import org.gradle.api.tasks.Optional;
 
 /**
@@ -37,6 +38,7 @@ public class ReplaceMatch implements RestTestTransformByParentObject {
     }
 
     @Override
+    @Internal
     public String getKeyToFind() {
         return "match";
     }

+ 64 - 0
buildSrc/src/main/java/org/elasticsearch/gradle/test/rest/transform/warnings/InjectAllowedWarnings.java

@@ -0,0 +1,64 @@
+/*
+ * 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 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+package org.elasticsearch.gradle.test.rest.transform.warnings;
+
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.elasticsearch.gradle.test.rest.transform.RestTestTransformByParentObject;
+import org.elasticsearch.gradle.test.rest.transform.feature.FeatureInjector;
+import org.gradle.api.tasks.Input;
+import org.gradle.api.tasks.Internal;
+
+import java.util.List;
+
+/**
+ * A transformation to inject an allowed warning.
+ */
+public class InjectAllowedWarnings extends FeatureInjector implements RestTestTransformByParentObject {
+
+    private static JsonNodeFactory jsonNodeFactory = JsonNodeFactory.withExactBigDecimals(false);
+
+    private final List<String> allowedWarnings;
+
+    /**
+     * @param allowedWarnings The allowed warnings to inject
+     */
+    public InjectAllowedWarnings(List<String> allowedWarnings) {
+        this.allowedWarnings = allowedWarnings;
+    }
+
+    @Override
+    public void transformTest(ObjectNode doNodeParent) {
+        ObjectNode doNodeValue = (ObjectNode) doNodeParent.get(getKeyToFind());
+        ArrayNode arrayWarnings = (ArrayNode) doNodeValue.get("allowed_warnings");
+        if (arrayWarnings == null) {
+            arrayWarnings = new ArrayNode(jsonNodeFactory);
+            doNodeValue.set("allowed_warnings", arrayWarnings);
+        }
+        allowedWarnings.forEach(arrayWarnings::add);
+    }
+
+    @Override
+    @Internal
+    public String getKeyToFind() {
+        return "do";
+    }
+
+    @Override
+    @Internal
+    public String getSkipFeatureName() {
+        return "allowed_warnings";
+    }
+
+    @Input
+    public List<String> getAllowedWarnings() {
+        return allowedWarnings;
+    }
+}

+ 79 - 0
buildSrc/src/main/java/org/elasticsearch/gradle/test/rest/transform/warnings/InjectWarnings.java

@@ -0,0 +1,79 @@
+/*
+ * 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 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+package org.elasticsearch.gradle.test.rest.transform.warnings;
+
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.elasticsearch.gradle.test.rest.transform.RestTestContext;
+import org.elasticsearch.gradle.test.rest.transform.RestTestTransformByParentObject;
+import org.elasticsearch.gradle.test.rest.transform.feature.FeatureInjector;
+import org.gradle.api.tasks.Input;
+import org.gradle.api.tasks.Internal;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * A transformation to inject an expected warning for a given test.
+ */
+public class InjectWarnings extends FeatureInjector implements RestTestTransformByParentObject {
+
+    private static JsonNodeFactory jsonNodeFactory = JsonNodeFactory.withExactBigDecimals(false);
+
+    private final List<String> warnings;
+    private final String testName;
+
+    /**
+     * @param warnings The warnings to inject
+     * @param testName The testName to inject
+     */
+    public InjectWarnings(List<String> warnings, String testName) {
+        this.warnings = warnings;
+        this.testName = Objects.requireNonNull(testName, "inject warnings is only supported for named tests");
+    }
+
+    @Override
+    public void transformTest(ObjectNode doNodeParent) {
+        ObjectNode doNodeValue = (ObjectNode) doNodeParent.get(getKeyToFind());
+        ArrayNode arrayWarnings = (ArrayNode) doNodeValue.get("warnings");
+        if (arrayWarnings == null) {
+            arrayWarnings = new ArrayNode(jsonNodeFactory);
+            doNodeValue.set("warnings", arrayWarnings);
+        }
+        warnings.forEach(arrayWarnings::add);
+    }
+
+    @Override
+    @Internal
+    public String getKeyToFind() {
+        return "do";
+    }
+
+    @Override
+    @Internal
+    public String getSkipFeatureName() {
+        return "warnings";
+    }
+
+    @Override
+    public boolean shouldApply(RestTestContext testContext) {
+        return testName.equals(testContext.getTestName());
+    }
+
+    @Input
+    public List<String> getWarnings() {
+        return warnings;
+    }
+
+    @Input
+    public String getTestName() {
+        return testName;
+    }
+}

+ 69 - 0
buildSrc/src/main/java/org/elasticsearch/gradle/test/rest/transform/warnings/RemoveWarnings.java

@@ -0,0 +1,69 @@
+/*
+ * 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 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+package org.elasticsearch.gradle.test.rest.transform.warnings;
+
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.elasticsearch.gradle.test.rest.transform.RestTestTransformByParentObject;
+import org.gradle.api.tasks.Input;
+import org.gradle.api.tasks.Internal;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * A transformation to to remove any warnings that match exactly.
+ * If this removes all of the warnings, this will not remove the feature from the setup and/or teardown and will leave behind an empty array
+ * While it would be more technically correct to do so, the effort/complexity does not warrant it, since for the expected usage it makes
+ * no difference.
+ */
+
+public class RemoveWarnings implements RestTestTransformByParentObject {
+
+    private final Set<String> warnings;
+
+    /**
+     * @param warnings The allowed warnings to inject
+     */
+    public RemoveWarnings(Set<String> warnings) {
+        this.warnings = warnings;
+    }
+
+    @Override
+    public void transformTest(ObjectNode doNodeParent) {
+        ObjectNode doNodeValue = (ObjectNode) doNodeParent.get(getKeyToFind());
+        ArrayNode arrayWarnings = (ArrayNode) doNodeValue.get("warnings");
+        if (arrayWarnings == null) {
+            return;
+        }
+
+        List<String> keepWarnings = new ArrayList<>();
+        arrayWarnings.elements().forEachRemaining(warning -> {
+            String warningValue = warning.textValue();
+            if (warnings.contains(warningValue) == false) {
+                keepWarnings.add(warningValue);
+            }
+
+        });
+        arrayWarnings.removeAll();
+        keepWarnings.forEach(arrayWarnings::add);
+    }
+
+    @Override
+    @Internal
+    public String getKeyToFind() {
+        return "do";
+    }
+
+    @Input
+    public Set<String> getWarnings() {
+        return warnings;
+    }
+}

+ 86 - 0
buildSrc/src/test/java/org/elasticsearch/gradle/test/rest/transform/TransformTests.java

@@ -31,6 +31,7 @@ import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.LongAdder;
 import java.util.stream.Collectors;
@@ -179,6 +180,91 @@ public abstract class TransformTests extends GradleUnitTestCase {
         return null;
     }
 
+    protected void validateBodyHasWarnings(String featureName, List<ObjectNode> tests, Set<String> expectedWarnings) {
+        validateBodyHasWarnings(featureName, null, tests, expectedWarnings);
+    }
+
+    protected void validateBodyHasWarnings(String featureName, String testName, List<ObjectNode> tests, Set<String> expectedWarnings) {
+        AtomicBoolean actuallyDidSomething = new AtomicBoolean(false);
+        tests.forEach(test -> {
+            Iterator<Map.Entry<String, JsonNode>> testsIterator = test.fields();
+            while (testsIterator.hasNext()) {
+                Map.Entry<String, JsonNode> testObject = testsIterator.next();
+                assertThat(testObject.getValue(), CoreMatchers.instanceOf(ArrayNode.class));
+                if (testName == null || testName.equals(testObject.getKey())) {
+                    ArrayNode testBody = (ArrayNode) testObject.getValue();
+                    testBody.forEach(arrayObject -> {
+                        assertThat(arrayObject, CoreMatchers.instanceOf(ObjectNode.class));
+                        ObjectNode testSection = (ObjectNode) arrayObject;
+                        if (testSection.get("do") != null) {
+                            ObjectNode doSection = (ObjectNode) testSection.get("do");
+                            assertThat(doSection.get(featureName), CoreMatchers.notNullValue());
+                            ArrayNode warningsNode = (ArrayNode) doSection.get(featureName);
+                            LongAdder assertions = new LongAdder();
+                            warningsNode.forEach(warning -> {
+                                if (expectedWarnings.contains(warning.asText())) {
+                                    assertions.increment();
+                                }
+                            });
+                            assertThat(assertions.intValue(), CoreMatchers.equalTo(expectedWarnings.size()));
+                            actuallyDidSomething.set(true);
+                        }
+                    });
+                }
+            }
+        });
+        assertTrue(actuallyDidSomething.get());
+    }
+
+    protected void validateBodyHasNoWarnings(String featureName, List<ObjectNode> tests) {
+        validateBodyHasNoWarnings(featureName, null, tests);
+    }
+
+    protected void validateBodyHasNoWarnings(String featureName, String testName, List<ObjectNode> tests) {
+        AtomicBoolean actuallyDidSomething = new AtomicBoolean(false);
+        tests.forEach(test -> {
+            Iterator<Map.Entry<String, JsonNode>> testsIterator = test.fields();
+            while (testsIterator.hasNext()) {
+                Map.Entry<String, JsonNode> testObject = testsIterator.next();
+                if (testName == null || testName.equals(testObject.getKey())) {
+                    assertThat(testObject.getValue(), CoreMatchers.instanceOf(ArrayNode.class));
+                    ArrayNode testBody = (ArrayNode) testObject.getValue();
+                    testBody.forEach(arrayObject -> {
+                        assertThat(arrayObject, CoreMatchers.instanceOf(ObjectNode.class));
+                        ObjectNode testSection = (ObjectNode) arrayObject;
+                        if (testSection.get("do") != null) {
+                            ObjectNode doSection = (ObjectNode) testSection.get("do");
+                            assertThat(doSection.get(featureName), CoreMatchers.nullValue());
+                            actuallyDidSomething.set(true);
+                        }
+                    });
+                }
+            }
+        });
+        assertTrue(actuallyDidSomething.get());
+    }
+
+    protected void validateBodyHasEmptyNoWarnings(String featureName, List<ObjectNode> tests) {
+        tests.forEach(test -> {
+            Iterator<Map.Entry<String, JsonNode>> testsIterator = test.fields();
+            while (testsIterator.hasNext()) {
+                Map.Entry<String, JsonNode> testObject = testsIterator.next();
+                assertThat(testObject.getValue(), CoreMatchers.instanceOf(ArrayNode.class));
+                ArrayNode testBody = (ArrayNode) testObject.getValue();
+                testBody.forEach(arrayObject -> {
+                    assertThat(arrayObject, CoreMatchers.instanceOf(ObjectNode.class));
+                    ObjectNode testSection = (ObjectNode) arrayObject;
+                    if (testSection.get("do") != null) {
+                        ObjectNode doSection = (ObjectNode) testSection.get("do");
+                        assertThat(doSection.get(featureName), CoreMatchers.notNullValue());
+                        ArrayNode warningsNode = (ArrayNode) doSection.get(featureName);
+                        assertTrue(warningsNode.isEmpty());
+                    }
+                });
+            }
+        });
+    }
+
     protected void validateBodyHasHeaders(List<ObjectNode> tests, Map<String, String> expectedHeaders) {
         tests.forEach(test -> {
             Iterator<Map.Entry<String, JsonNode>> testsIterator = test.fields();

+ 70 - 0
buildSrc/src/test/java/org/elasticsearch/gradle/test/rest/transform/warnings/InjectAllowedWarningsTests.java

@@ -0,0 +1,70 @@
+/*
+ * 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 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+package org.elasticsearch.gradle.test.rest.transform.warnings;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.elasticsearch.gradle.test.rest.transform.RestTestTransform;
+import org.elasticsearch.gradle.test.rest.transform.feature.InjectFeatureTests;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+public class InjectAllowedWarningsTests extends InjectFeatureTests {
+
+    Set<String> addWarnings = Set.of("added warning");
+    private static final String ALLOWED_WARNINGS = "allowed_warnings";
+
+    /**
+     * test file does not any allowed warnings defined
+     */
+    @Test
+    public void testInjectAllowedWarningsNoPreExisting() throws Exception {
+        String testName = "/rest/transform/warnings/without_existing_warnings.yml";
+        List<ObjectNode> tests = getTests(testName);
+        validateSetupDoesNotExist(tests);
+        List<ObjectNode> transformedTests = transformTests(tests);
+        printTest(testName, transformedTests);
+        validateSetupAndTearDown(transformedTests);
+        validateBodyHasWarnings(ALLOWED_WARNINGS, transformedTests, addWarnings);
+    }
+
+    /**
+     * test file has preexisting allowed warnings
+     */
+    @Test
+    public void testInjectAllowedWarningsWithPreExisting() throws Exception {
+        String testName = "/rest/transform/warnings/with_existing_allowed_warnings.yml";
+        List<ObjectNode> tests = getTests(testName);
+        validateSetupExist(tests);
+        validateBodyHasWarnings(ALLOWED_WARNINGS, tests, Set.of("a", "b"));
+        List<ObjectNode> transformedTests = transformTests(tests);
+        printTest(testName, transformedTests);
+        validateSetupAndTearDown(transformedTests);
+        validateBodyHasWarnings(ALLOWED_WARNINGS, tests, Set.of("a", "b"));
+        validateBodyHasWarnings(ALLOWED_WARNINGS, tests, addWarnings);
+    }
+
+    @Override
+    protected List<String> getKnownFeatures() {
+        return Collections.singletonList(ALLOWED_WARNINGS);
+    }
+
+    @Override
+    protected List<RestTestTransform<?>> getTransformations() {
+        return Collections.singletonList(new InjectAllowedWarnings(new ArrayList<>(addWarnings)));
+    }
+
+    @Override
+    protected boolean getHumanDebug() {
+        return false;
+    }
+}

+ 87 - 0
buildSrc/src/test/java/org/elasticsearch/gradle/test/rest/transform/warnings/InjectWarningsTests.java

@@ -0,0 +1,87 @@
+/*
+ * 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 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+package org.elasticsearch.gradle.test.rest.transform.warnings;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.elasticsearch.gradle.test.rest.transform.RestTestTransform;
+import org.elasticsearch.gradle.test.rest.transform.feature.InjectFeatureTests;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+public class InjectWarningsTests extends InjectFeatureTests {
+    Set<String> addWarnings = Set.of("added warning");
+    private static final String WARNINGS = "warnings";
+
+    /**
+     * inject warning requires a test name to insert
+     */
+    @Test
+    public void testInjectWarningsRequiresTestName() throws Exception {
+        String testName = "/rest/transform/warnings/without_existing_warnings.yml";
+        List<ObjectNode> tests = getTests(testName);
+        validateSetupDoesNotExist(tests);
+        assertEquals(
+            "inject warnings is only supported for named tests",
+            expectThrows(
+                NullPointerException.class,
+                () -> transformTests(tests, Collections.singletonList(new InjectWarnings(new ArrayList<>(addWarnings), null)))
+            ).getMessage()
+        );
+    }
+
+    /**
+     * test file does not any warnings defined
+     */
+    @Test
+    public void testInjectWarningsNoPreExisting() throws Exception {
+        String testName = "/rest/transform/warnings/without_existing_warnings.yml";
+        List<ObjectNode> tests = getTests(testName);
+        validateSetupDoesNotExist(tests);
+        List<ObjectNode> transformedTests = transformTests(tests);
+        printTest(testName, transformedTests);
+        validateSetupAndTearDown(transformedTests);
+        validateBodyHasWarnings(WARNINGS, "Test warnings", transformedTests, addWarnings);
+        validateBodyHasNoWarnings(WARNINGS, "Test another", transformedTests);
+    }
+
+    /**
+     * test file has preexisting warnings
+     */
+    @Test
+    public void testInjectWarningsWithPreExisting() throws Exception {
+        String testName = "/rest/transform/warnings/with_existing_warnings.yml";
+        List<ObjectNode> tests = getTests(testName);
+        validateSetupExist(tests);
+        validateBodyHasWarnings(WARNINGS, tests, Set.of("a", "b"));
+        List<ObjectNode> transformedTests = transformTests(tests);
+        printTest(testName, transformedTests);
+        validateSetupAndTearDown(transformedTests);
+        validateBodyHasWarnings(WARNINGS, tests, Set.of("a", "b"));
+        validateBodyHasWarnings(WARNINGS, "Test warnings", tests, addWarnings);
+    }
+
+    @Override
+    protected List<String> getKnownFeatures() {
+        return Collections.singletonList(WARNINGS);
+    }
+
+    @Override
+    protected List<RestTestTransform<?>> getTransformations() {
+        return Collections.singletonList(new InjectWarnings(new ArrayList<>(addWarnings), "Test warnings"));
+    }
+
+    @Override
+    protected boolean getHumanDebug() {
+        return true;
+    }
+}

+ 78 - 0
buildSrc/src/test/java/org/elasticsearch/gradle/test/rest/transform/warnings/RemoveWarningsTests.java

@@ -0,0 +1,78 @@
+/*
+ * 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 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+package org.elasticsearch.gradle.test.rest.transform.warnings;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.elasticsearch.gradle.test.rest.transform.RestTestTransform;
+import org.elasticsearch.gradle.test.rest.transform.TransformTests;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+public class RemoveWarningsTests extends TransformTests {
+
+    private static final String WARNINGS = "warnings";
+
+    /**
+     * test file does not any warnings defined
+     */
+    @Test
+    public void testRemoveWarningsNoPreExisting() throws Exception {
+        String testName = "/rest/transform/warnings/without_existing_warnings.yml";
+        List<ObjectNode> tests = getTests(testName);
+        validateSetupDoesNotExist(tests);
+        List<ObjectNode> transformedTests = transformTests(tests);
+        printTest(testName, transformedTests);
+        validateSetupDoesNotExist(transformedTests);
+        validateBodyHasNoWarnings(WARNINGS, transformedTests);
+    }
+
+    /**
+     * test file has preexisting multiple warnings
+     */
+    @Test
+    public void testRemoveWarningWithPreExisting() throws Exception {
+        String testName = "/rest/transform/warnings/with_existing_warnings.yml";
+        List<ObjectNode> tests = getTests(testName);
+        validateSetupExist(tests);
+        validateBodyHasWarnings(WARNINGS, tests, Set.of("a", "b"));
+        List<ObjectNode> transformedTests = transformTests(tests);
+        printTest(testName, transformedTests);
+        validateSetupAndTearDown(transformedTests);
+        validateBodyHasWarnings(WARNINGS, tests, Set.of("b"));
+    }
+
+    /**
+     * test file has preexisting single warning
+     */
+    @Test
+    public void testRemoveWarningWithSinglePreExisting() throws Exception {
+        // For simplicity, when removing the last item, it does not remove the headers/teardown and leaves an empty array
+        String testName = "/rest/transform/warnings/with_existing_single_warnings.yml";
+        List<ObjectNode> tests = getTests(testName);
+        validateSetupExist(tests);
+        validateBodyHasWarnings(WARNINGS, tests, Set.of("a"));
+        List<ObjectNode> transformedTests = transformTests(tests);
+        printTest(testName, transformedTests);
+        validateSetupAndTearDown(transformedTests);
+        validateBodyHasEmptyNoWarnings(WARNINGS, tests);
+    }
+
+    @Override
+    protected List<RestTestTransform<?>> getTransformations() {
+        return Collections.singletonList(new RemoveWarnings(Set.of("a")));
+    }
+
+    @Override
+    protected boolean getHumanDebug() {
+        return true;
+    }
+}

+ 14 - 0
buildSrc/src/test/resources/rest/transform/warnings/with_existing_allowed_warnings.yml

@@ -0,0 +1,14 @@
+---
+setup:
+  - skip:
+      features: allowed_warnings
+---
+"Test with existing allowed warnings":
+  - do:
+      allowed_warnings:
+        - "a"
+        - "b"
+      something:
+        id: "something"
+  - match: { acknowledged: true }
+

+ 13 - 0
buildSrc/src/test/resources/rest/transform/warnings/with_existing_single_warnings.yml

@@ -0,0 +1,13 @@
+---
+setup:
+  - skip:
+      features: warnings
+---
+"Test warnings":
+  - do:
+      warnings:
+        - "a"
+      something:
+        id: "something"
+  - match: { acknowledged: true }
+

+ 23 - 0
buildSrc/src/test/resources/rest/transform/warnings/with_existing_warnings.yml

@@ -0,0 +1,23 @@
+---
+setup:
+  - skip:
+      features: warnings
+---
+"Test warnings":
+  - do:
+      warnings:
+        - "a"
+        - "b"
+      something:
+        id: "something"
+  - match: { acknowledged: true }
+---
+"Not the test to change":
+  - do:
+      warnings:
+        - "a"
+        - "b"
+      something:
+        id: "something"
+  - match: { acknowledged: true }
+

+ 13 - 0
buildSrc/src/test/resources/rest/transform/warnings/without_existing_warnings.yml

@@ -0,0 +1,13 @@
+---
+"Test warnings":
+  - do:
+      something:
+        id: "something"
+  - match: { acknowledged: true }
+---
+"Test another":
+  - do:
+      something:
+        id: "something"
+  - match: { acknowledged: true }
+