From 09260570b94c5c3768a9f5993091561c634ee718 Mon Sep 17 00:00:00 2001 From: Rene Groeschke Date: Thu, 5 Aug 2021 20:56:52 +0200 Subject: [PATCH] Introduce Gradle plugin for setup gradle test security policies (#76167) Test execution hangs when building Elasticsearch plugins and extending ESTestCase fixes #76136 --- .../internal/ElasticsearchTestBasePlugin.java | 18 ++---- .../internal/test/DistroTestPlugin.java | 1 + .../internal/test/RestTestBasePlugin.java | 1 + .../testfixtures/TestFixturesPlugin.java | 2 +- build-tools/build.gradle | 4 ++ ...GradleTestPolicySetupPluginFuncTest.groovy | 63 +++++++++++++++++++ .../gradle/plugin/PluginBuildPlugin.java | 2 + .../test/GradleTestPolicySetupPlugin.java | 35 +++++++++++ ...emPropertyCommandLineArgumentProvider.java | 2 +- 9 files changed, 113 insertions(+), 15 deletions(-) create mode 100644 build-tools/src/integTest/groovy/org/elasticsearch/gradle/test/GradleTestPolicySetupPluginFuncTest.groovy create mode 100644 build-tools/src/main/java/org/elasticsearch/gradle/test/GradleTestPolicySetupPlugin.java rename {build-tools-internal/src/main/java/org/elasticsearch/gradle/internal => build-tools/src/main/java/org/elasticsearch/gradle}/test/SystemPropertyCommandLineArgumentProvider.java (97%) diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/ElasticsearchTestBasePlugin.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/ElasticsearchTestBasePlugin.java index b26dff17c10cd..78fe3412c4a6f 100644 --- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/ElasticsearchTestBasePlugin.java +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/ElasticsearchTestBasePlugin.java @@ -11,7 +11,8 @@ import com.github.jengelman.gradle.plugins.shadow.ShadowBasePlugin; import org.elasticsearch.gradle.OS; import org.elasticsearch.gradle.internal.test.SimpleCommandLineArgumentProvider; -import org.elasticsearch.gradle.internal.test.SystemPropertyCommandLineArgumentProvider; +import org.elasticsearch.gradle.test.GradleTestPolicySetupPlugin; +import org.elasticsearch.gradle.test.SystemPropertyCommandLineArgumentProvider; import org.elasticsearch.gradle.internal.info.BuildParams; import org.elasticsearch.gradle.internal.info.GlobalBuildInfoPlugin; import org.elasticsearch.gradle.internal.test.ErrorReportingTestListener; @@ -40,6 +41,7 @@ public class ElasticsearchTestBasePlugin implements Plugin { @Override public void apply(Project project) { + project.getPluginManager().apply(GradleTestPolicySetupPlugin.class); // for fips mode check project.getRootProject().getPluginManager().apply(GlobalBuildInfoPlugin.class); // Default test task should run only unit tests @@ -118,12 +120,8 @@ public void execute(Task t) { Map sysprops = Map.of( "java.awt.headless", "true", - "tests.gradle", - "true", "tests.artifact", project.getName(), - "tests.task", - test.getPath(), "tests.security.manager", "true", "jna.nosys", @@ -139,14 +137,8 @@ public void execute(Task t) { } // don't track these as inputs since they contain absolute paths and break cache relocatability - File gradleHome = project.getGradle().getGradleUserHomeDir(); - String gradleVersion = project.getGradle().getGradleVersion(); - nonInputProperties.systemProperty("gradle.dist.lib", new File(project.getGradle().getGradleHomeDir(), "lib")); - nonInputProperties.systemProperty( - "gradle.worker.jar", - gradleHome + "/caches/" + gradleVersion + "/workerMain/gradle-worker.jar" - ); - nonInputProperties.systemProperty("gradle.user.home", gradleHome); + File gradleUserHome = project.getGradle().getGradleUserHomeDir(); + nonInputProperties.systemProperty("gradle.user.home", gradleUserHome); // we use 'temp' relative to CWD since this is per JVM and tests are forbidden from writing to CWD nonInputProperties.systemProperty("java.io.tmpdir", test.getWorkingDir().toPath().resolve("temp")); diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/DistroTestPlugin.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/DistroTestPlugin.java index 52dfbc5907e6f..a23fe505325bd 100644 --- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/DistroTestPlugin.java +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/DistroTestPlugin.java @@ -21,6 +21,7 @@ import org.elasticsearch.gradle.internal.docker.DockerSupportService; import org.elasticsearch.gradle.internal.info.BuildParams; import org.elasticsearch.gradle.internal.InternalDistributionDownloadPlugin; +import org.elasticsearch.gradle.test.SystemPropertyCommandLineArgumentProvider; import org.elasticsearch.gradle.util.GradleUtils; import org.elasticsearch.gradle.internal.conventions.util.Util; import org.elasticsearch.gradle.internal.vagrant.VagrantBasePlugin; diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/RestTestBasePlugin.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/RestTestBasePlugin.java index 57332ae1a0368..f14cc4fd658e0 100644 --- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/RestTestBasePlugin.java +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/RestTestBasePlugin.java @@ -12,6 +12,7 @@ import org.elasticsearch.gradle.internal.ElasticsearchTestBasePlugin; import org.elasticsearch.gradle.internal.FixtureStop; import org.elasticsearch.gradle.internal.InternalTestClustersPlugin; +import org.elasticsearch.gradle.test.SystemPropertyCommandLineArgumentProvider; import org.elasticsearch.gradle.testclusters.ElasticsearchCluster; import org.elasticsearch.gradle.testclusters.StandaloneRestIntegTestTask; import org.elasticsearch.gradle.testclusters.TestClustersPlugin; diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/testfixtures/TestFixturesPlugin.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/testfixtures/TestFixturesPlugin.java index 8a1c758706100..d9ad10f866ebc 100644 --- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/testfixtures/TestFixturesPlugin.java +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/testfixtures/TestFixturesPlugin.java @@ -13,7 +13,7 @@ import com.avast.gradle.dockercompose.tasks.ComposeDown; import com.avast.gradle.dockercompose.tasks.ComposePull; import com.avast.gradle.dockercompose.tasks.ComposeUp; -import org.elasticsearch.gradle.internal.test.SystemPropertyCommandLineArgumentProvider; +import org.elasticsearch.gradle.test.SystemPropertyCommandLineArgumentProvider; import org.elasticsearch.gradle.internal.docker.DockerSupportPlugin; import org.elasticsearch.gradle.internal.docker.DockerSupportService; import org.elasticsearch.gradle.internal.info.BuildParams; diff --git a/build-tools/build.gradle b/build-tools/build.gradle index b8444235441a8..cd49a7bb3c0a3 100644 --- a/build-tools/build.gradle +++ b/build-tools/build.gradle @@ -54,6 +54,10 @@ gradlePlugin { id = 'elasticsearch.reaper' implementationClass = 'org.elasticsearch.gradle.ReaperPlugin' } + testpermissions { + id = 'elasticsearch.test-gradle-policy' + implementationClass = 'org.elasticsearch.gradle.test.GradleTestPolicySetupPlugin' + } } } diff --git a/build-tools/src/integTest/groovy/org/elasticsearch/gradle/test/GradleTestPolicySetupPluginFuncTest.groovy b/build-tools/src/integTest/groovy/org/elasticsearch/gradle/test/GradleTestPolicySetupPluginFuncTest.groovy new file mode 100644 index 0000000000000..6d72dc0a611e5 --- /dev/null +++ b/build-tools/src/integTest/groovy/org/elasticsearch/gradle/test/GradleTestPolicySetupPluginFuncTest.groovy @@ -0,0 +1,63 @@ +/* + * 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 + +import org.elasticsearch.gradle.fixtures.AbstractGradleFuncTest +import org.gradle.testkit.runner.TaskOutcome + +class GradleTestPolicySetupPluginFuncTest extends AbstractGradleFuncTest { + + def "configures test tasks"() { + given: + file("src/test/java/org/acme/SysPropTest.java") << """ + package org.acme; + + import static org.junit.Assert.*; + import org.junit.After; + import org.junit.Before; + import org.junit.Test; + + public class SysPropTest { + @Test + public void verifySysProps() { + assertNotNull(System.getProperty("gradle.dist.lib")); + assertNotNull(System.getProperty("gradle.worker.jar")); + assertEquals(System.getProperty("tests.gradle"), "true"); + assertEquals(System.getProperty("tests.task"), ":test"); + } + } + """ + + buildFile << """ + plugins { + id "elasticsearch.test-gradle-policy" + id "java" + } + + repositories { + mavenCentral() + } + + dependencies { + testImplementation "junit:junit:4.13" + } + """ + + when: + def result = gradleRunner('test', '-g', "guh1").build() + + then: + result.task(":test").outcome == TaskOutcome.SUCCESS + + when: // changing gradle user home + result = gradleRunner('test', '-g', "guh2").build() + then: // still up-to-date + result.task(":test").outcome == TaskOutcome.UP_TO_DATE + } +} \ No newline at end of file diff --git a/build-tools/src/main/java/org/elasticsearch/gradle/plugin/PluginBuildPlugin.java b/build-tools/src/main/java/org/elasticsearch/gradle/plugin/PluginBuildPlugin.java index 7ca91770a2ee0..54674d5476f95 100644 --- a/build-tools/src/main/java/org/elasticsearch/gradle/plugin/PluginBuildPlugin.java +++ b/build-tools/src/main/java/org/elasticsearch/gradle/plugin/PluginBuildPlugin.java @@ -16,6 +16,7 @@ import org.elasticsearch.gradle.VersionProperties; import org.elasticsearch.gradle.dependencies.CompileOnlyResolvePlugin; import org.elasticsearch.gradle.jarhell.JarHellPlugin; +import org.elasticsearch.gradle.test.GradleTestPolicySetupPlugin; import org.elasticsearch.gradle.testclusters.ElasticsearchCluster; import org.elasticsearch.gradle.testclusters.RunTask; import org.elasticsearch.gradle.testclusters.TestClustersPlugin; @@ -59,6 +60,7 @@ public void apply(final Project project) { project.getPluginManager().apply(TestClustersPlugin.class); project.getPluginManager().apply(CompileOnlyResolvePlugin.class); project.getPluginManager().apply(JarHellPlugin.class); + project.getPluginManager().apply(GradleTestPolicySetupPlugin.class); var extension = project.getExtensions().create(PLUGIN_EXTENSION_NAME, PluginPropertiesExtension.class, project); configureDependencies(project); diff --git a/build-tools/src/main/java/org/elasticsearch/gradle/test/GradleTestPolicySetupPlugin.java b/build-tools/src/main/java/org/elasticsearch/gradle/test/GradleTestPolicySetupPlugin.java new file mode 100644 index 0000000000000..a1da860abe26a --- /dev/null +++ b/build-tools/src/main/java/org/elasticsearch/gradle/test/GradleTestPolicySetupPlugin.java @@ -0,0 +1,35 @@ +/* + * 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; + +import org.gradle.api.Plugin; +import org.gradle.api.Project; +import org.gradle.api.invocation.Gradle; +import org.gradle.api.tasks.testing.Test; + +public class GradleTestPolicySetupPlugin implements Plugin { + + @Override + public void apply(Project project) { + Gradle gradle = project.getGradle(); + project.getTasks().withType(Test.class).configureEach(test -> { + test.systemProperty("tests.gradle", true); + test.systemProperty("tests.task", test.getPath()); + + SystemPropertyCommandLineArgumentProvider nonInputProperties = new SystemPropertyCommandLineArgumentProvider(); + // don't track these as inputs since they contain absolute paths and break cache relocatability + nonInputProperties.systemProperty("gradle.dist.lib", gradle.getGradleHomeDir().getAbsolutePath() + "/lib"); + nonInputProperties.systemProperty( + "gradle.worker.jar", + gradle.getGradleUserHomeDir().getAbsolutePath() + "/caches/" + gradle.getGradleVersion() + "/workerMain/gradle-worker.jar" + ); + test.getJvmArgumentProviders().add(nonInputProperties); + }); + } +} diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/SystemPropertyCommandLineArgumentProvider.java b/build-tools/src/main/java/org/elasticsearch/gradle/test/SystemPropertyCommandLineArgumentProvider.java similarity index 97% rename from build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/SystemPropertyCommandLineArgumentProvider.java rename to build-tools/src/main/java/org/elasticsearch/gradle/test/SystemPropertyCommandLineArgumentProvider.java index de00c0cd4f643..e5f4e7254d610 100644 --- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/test/SystemPropertyCommandLineArgumentProvider.java +++ b/build-tools/src/main/java/org/elasticsearch/gradle/test/SystemPropertyCommandLineArgumentProvider.java @@ -5,7 +5,7 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -package org.elasticsearch.gradle.internal.test; +package org.elasticsearch.gradle.test; import org.gradle.api.tasks.Input; import org.gradle.process.CommandLineArgumentProvider;