diff --git a/buildSrc/src/main/resources/forbidden/all-signatures.txt b/buildSrc/src/main/resources/forbidden/all-signatures.txt index 321202c52f3..0809cdab9c2 100644 --- a/buildSrc/src/main/resources/forbidden/all-signatures.txt +++ b/buildSrc/src/main/resources/forbidden/all-signatures.txt @@ -104,4 +104,11 @@ java.lang.Thread#getAllStackTraces() @defaultMessage Please do not terminate the application java.lang.System#exit(int) java.lang.Runtime#exit(int) -java.lang.Runtime#halt(int) \ No newline at end of file +java.lang.Runtime#halt(int) + +@defaultMessage Treat system properties as immutable +java.lang.System#setProperties(java.util.Properties) +java.lang.System#setProperty(java.lang.String,java.lang.String) +java.lang.System#clearProperty(java.lang.String) +java.lang.System#getProperties() @ Use BootstrapInfo.getSystemProperties for a read-only view + diff --git a/core/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java b/core/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java index dce2e8b8cde..3a0ddf1c050 100644 --- a/core/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java +++ b/core/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java @@ -138,6 +138,7 @@ final class Bootstrap { // Force probes to be loaded ProcessProbe.getInstance(); OsProbe.getInstance(); + JvmInfo.jvmInfo(); } private void setup(boolean addShutdownHook, Settings settings, Environment environment) throws Exception { @@ -230,13 +231,20 @@ final class Bootstrap { } } + /** Set the system property before anything has a chance to trigger its use */ + // TODO: why? is it just a bad default somewhere? or is it some BS around 'but the client' garbage <-- my guess + @SuppressForbidden(reason = "sets logger prefix on initialization") + static void initLoggerPrefix() { + System.setProperty("es.logger.prefix", ""); + } + /** * This method is invoked by {@link Elasticsearch#main(String[])} * to startup elasticsearch. */ static void init(String[] args) throws Throwable { // Set the system property before anything has a chance to trigger its use - System.setProperty("es.logger.prefix", ""); + initLoggerPrefix(); BootstrapCLIParser bootstrapCLIParser = new BootstrapCLIParser(); CliTool.ExitStatus status = bootstrapCLIParser.execute(args); diff --git a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCLIParser.java b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCLIParser.java index 1e5175b4e5d..51a16f104bc 100644 --- a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCLIParser.java +++ b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCLIParser.java @@ -23,6 +23,7 @@ import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.Option; import org.elasticsearch.Build; import org.elasticsearch.common.Strings; +import org.elasticsearch.common.SuppressForbidden; import org.elasticsearch.common.cli.CliTool; import org.elasticsearch.common.cli.CliToolConfig; import org.elasticsearch.common.cli.Terminal; @@ -100,6 +101,8 @@ final class BootstrapCLIParser extends CliTool { .stopAtNonOption(true) // needed to parse the --foo.bar options, so this parser must be lenient .build(); + // TODO: don't use system properties as a way to do this, its horrible... + @SuppressForbidden(reason = "Sets system properties passed as CLI parameters") public static Command parse(Terminal terminal, CommandLine cli) { if (cli.hasOption("V")) { return Version.parse(terminal, cli); diff --git a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapInfo.java b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapInfo.java index f0cc89dfeec..bb83dfaaf67 100644 --- a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapInfo.java +++ b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapInfo.java @@ -19,9 +19,15 @@ package org.elasticsearch.bootstrap; +import org.elasticsearch.common.SuppressForbidden; + +import java.util.Dictionary; +import java.util.Enumeration; + /** * Exposes system startup information */ +@SuppressForbidden(reason = "exposes read-only view of system properties") public final class BootstrapInfo { /** no instantiation */ @@ -57,4 +63,61 @@ public final class BootstrapInfo { * This is not a full URL, just a path. */ public static final String UNTRUSTED_CODEBASE = "/untrusted"; + + // create a view of sysprops map that does not allow modifications + // this must be done this way (e.g. versus an actual typed map), because + // some test methods still change properties, so whitelisted changes must + // be reflected in this this view. + private static final Dictionary SYSTEM_PROPERTIES; + static { + final Dictionary sysprops = System.getProperties(); + SYSTEM_PROPERTIES = new Dictionary() { + + @Override + public int size() { + return sysprops.size(); + } + + @Override + public boolean isEmpty() { + return sysprops.isEmpty(); + } + + @Override + public Enumeration keys() { + return sysprops.keys(); + } + + @Override + public Enumeration elements() { + return sysprops.elements(); + } + + @Override + public Object get(Object key) { + return sysprops.get(key); + } + + @Override + public Object put(Object key, Object value) { + throw new UnsupportedOperationException("treat system properties as immutable"); + } + + @Override + public Object remove(Object key) { + throw new UnsupportedOperationException("treat system properties as immutable"); + } + }; + } + + /** + * Returns a read-only view of all system properties + */ + public static Dictionary getSystemProperties() { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPropertyAccess("*"); + } + return SYSTEM_PROPERTIES; + } } diff --git a/core/src/main/java/org/elasticsearch/common/logging/log4j/LogConfigurator.java b/core/src/main/java/org/elasticsearch/common/logging/log4j/LogConfigurator.java index 5e7517efc19..e0d5f15630a 100644 --- a/core/src/main/java/org/elasticsearch/common/logging/log4j/LogConfigurator.java +++ b/core/src/main/java/org/elasticsearch/common/logging/log4j/LogConfigurator.java @@ -21,6 +21,7 @@ package org.elasticsearch.common.logging.log4j; import org.apache.log4j.PropertyConfigurator; import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.bootstrap.BootstrapInfo; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsException; import org.elasticsearch.env.Environment; @@ -106,8 +107,8 @@ public class LogConfigurator { resolveConfig(environment, settingsBuilder); } settingsBuilder - .putProperties("elasticsearch.", System.getProperties()) - .putProperties("es.", System.getProperties()); + .putProperties("elasticsearch.", BootstrapInfo.getSystemProperties()) + .putProperties("es.", BootstrapInfo.getSystemProperties()); // add custom settings after config was added so that they are not overwritten by config settingsBuilder.put(settings); settingsBuilder.replacePropertyPlaceholders(); diff --git a/core/src/main/java/org/elasticsearch/common/settings/Settings.java b/core/src/main/java/org/elasticsearch/common/settings/Settings.java index 663abd746f0..5e083a9e740 100644 --- a/core/src/main/java/org/elasticsearch/common/settings/Settings.java +++ b/core/src/main/java/org/elasticsearch/common/settings/Settings.java @@ -46,13 +46,14 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.Dictionary; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Properties; +import java.util.Objects; import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; @@ -1028,9 +1029,9 @@ public final class Settings implements ToXContent { /** * Sets all the provided settings. */ - public Builder put(Properties properties) { - for (Map.Entry entry : properties.entrySet()) { - map.put((String) entry.getKey(), (String) entry.getValue()); + public Builder put(Dictionary properties) { + for (Object key : Collections.list(properties.keys())) { + map.put(Objects.toString(key), Objects.toString(properties.get(key))); } return this; } @@ -1096,10 +1097,10 @@ public final class Settings implements ToXContent { * @param properties The properties to put * @return The builder */ - public Builder putProperties(String prefix, Properties properties) { - for (Object key1 : properties.keySet()) { - String key = (String) key1; - String value = properties.getProperty(key); + public Builder putProperties(String prefix, Dictionary properties) { + for (Object key1 : Collections.list(properties.keys())) { + String key = Objects.toString(key1); + String value = Objects.toString(properties.get(key)); if (key.startsWith(prefix)) { map.put(key.substring(prefix.length()), value); } @@ -1114,10 +1115,10 @@ public final class Settings implements ToXContent { * @param properties The properties to put * @return The builder */ - public Builder putProperties(String prefix, Properties properties, String[] ignorePrefixes) { - for (Object key1 : properties.keySet()) { - String key = (String) key1; - String value = properties.getProperty(key); + public Builder putProperties(String prefix, Dictionary properties, String[] ignorePrefixes) { + for (Object key1 : Collections.list(properties.keys())) { + String key = Objects.toString(key1); + String value = Objects.toString(properties.get(key)); if (key.startsWith(prefix)) { boolean ignore = false; for (String ignorePrefix : ignorePrefixes) { diff --git a/core/src/main/java/org/elasticsearch/http/netty/NettyHttpServerTransport.java b/core/src/main/java/org/elasticsearch/http/netty/NettyHttpServerTransport.java index 2e9ca7ee420..ebc655ae4a5 100644 --- a/core/src/main/java/org/elasticsearch/http/netty/NettyHttpServerTransport.java +++ b/core/src/main/java/org/elasticsearch/http/netty/NettyHttpServerTransport.java @@ -20,6 +20,7 @@ package org.elasticsearch.http.netty; import org.elasticsearch.common.Booleans; +import org.elasticsearch.common.SuppressForbidden; import org.elasticsearch.common.component.AbstractLifecycleComponent; import org.elasticsearch.common.inject.Inject; import org.elasticsearch.common.netty.NettyUtils; @@ -138,6 +139,8 @@ public class NettyHttpServerTransport extends AbstractLifecycleComponent gcMxBeans = ManagementFactory.getGarbageCollectorMXBeans(); info.gcCollectors = new String[gcMxBeans.size()]; @@ -104,6 +105,11 @@ public class JvmInfo implements Streamable, ToXContent { } public static JvmInfo jvmInfo() { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(new ManagementPermission("monitor")); + sm.checkPropertyAccess("*"); + } return INSTANCE; } diff --git a/core/src/main/java/org/elasticsearch/node/internal/InternalSettingsPreparer.java b/core/src/main/java/org/elasticsearch/node/internal/InternalSettingsPreparer.java index 3f35ddf033c..7bede53e7ec 100644 --- a/core/src/main/java/org/elasticsearch/node/internal/InternalSettingsPreparer.java +++ b/core/src/main/java/org/elasticsearch/node/internal/InternalSettingsPreparer.java @@ -20,6 +20,8 @@ package org.elasticsearch.node.internal; import java.nio.charset.StandardCharsets; + +import org.elasticsearch.bootstrap.BootstrapInfo; import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.common.Booleans; import org.elasticsearch.common.Strings; @@ -125,11 +127,11 @@ public class InternalSettingsPreparer { if (useSystemProperties(input)) { if (loadDefaults) { for (String prefix : PROPERTY_DEFAULTS_PREFIXES) { - output.putProperties(prefix, System.getProperties()); + output.putProperties(prefix, BootstrapInfo.getSystemProperties()); } } for (String prefix : PROPERTY_PREFIXES) { - output.putProperties(prefix, System.getProperties(), PROPERTY_DEFAULTS_PREFIXES); + output.putProperties(prefix, BootstrapInfo.getSystemProperties(), PROPERTY_DEFAULTS_PREFIXES); } } output.replacePropertyPlaceholders(); diff --git a/core/src/main/java/org/elasticsearch/transport/netty/NettyTransport.java b/core/src/main/java/org/elasticsearch/transport/netty/NettyTransport.java index e67904a6db2..ab39a35d224 100644 --- a/core/src/main/java/org/elasticsearch/transport/netty/NettyTransport.java +++ b/core/src/main/java/org/elasticsearch/transport/netty/NettyTransport.java @@ -24,6 +24,7 @@ import org.elasticsearch.Version; import org.elasticsearch.cluster.node.DiscoveryNode; import org.elasticsearch.common.Booleans; import org.elasticsearch.common.Strings; +import org.elasticsearch.common.SuppressForbidden; import org.elasticsearch.common.bytes.ReleasablePagedBytesReference; import org.elasticsearch.common.component.AbstractLifecycleComponent; import org.elasticsearch.common.compress.CompressorFactory; @@ -205,6 +206,8 @@ public class NettyTransport extends AbstractLifecycleComponent implem final ScheduledPing scheduledPing; @Inject + @SuppressForbidden(reason = "sets org.jboss.netty.epollBugWorkaround based on netty.epollBugWorkaround") + // TODO: why be confusing like this? just let the user do it with the netty parameter instead! public NettyTransport(Settings settings, ThreadPool threadPool, NetworkService networkService, BigArrays bigArrays, Version version, NamedWriteableRegistry namedWriteableRegistry) { super(settings); this.threadPool = threadPool; diff --git a/core/src/main/resources/org/elasticsearch/bootstrap/security.policy b/core/src/main/resources/org/elasticsearch/bootstrap/security.policy index fb68efe85b6..98d5a1944d9 100644 --- a/core/src/main/resources/org/elasticsearch/bootstrap/security.policy +++ b/core/src/main/resources/org/elasticsearch/bootstrap/security.policy @@ -48,8 +48,37 @@ grant { // Allow connecting to the internet anywhere permission java.net.SocketPermission "*", "accept,connect,resolve"; - // Allow read/write to all system properties - permission java.util.PropertyPermission "*", "read,write"; + // Allow read access to all system properties + permission java.util.PropertyPermission "*", "read"; + + // TODO: clean all these property writes up, and don't allow any more in. these are all bogus! + + // LuceneTestCase randomization (locale/timezone/cpus/ssd) + // TODO: put these in doPrivileged and move these to test-framework.policy + permission java.util.PropertyPermission "user.language", "write"; + permission java.util.PropertyPermission "user.timezone", "write"; + permission java.util.PropertyPermission "lucene.cms.override_core_count", "write"; + permission java.util.PropertyPermission "lucene.cms.override_spins", "write"; + // messiness in LuceneTestCase: do the above, or clean this up, or simply allow to fail if its denied + permission java.util.PropertyPermission "solr.solr.home", "write"; + permission java.util.PropertyPermission "solr.data.dir", "write"; + permission java.util.PropertyPermission "solr.directoryFactory", "write"; + + // set by ESTestCase to improve test reproducibility + // TODO: set this with gradle or some other way that repros with seed? + permission java.util.PropertyPermission "es.processors.override", "write"; + // set by CLIToolTestCase + // TODO: do this differently? or test commandline tools differently? + permission java.util.PropertyPermission "es.default.path.home", "write"; + + // TODO: these simply trigger a noisy warning if its unable to clear the properties + // fix that in randomizedtesting + permission java.util.PropertyPermission "junit4.childvm.count", "write"; + permission java.util.PropertyPermission "junit4.childvm.id", "write"; + + // set by NettyTransport/NettyHttpServerTransport based on another parameter + // TODO: look into this and decide if users should simply set the actual sysprop?! + permission java.util.PropertyPermission "org.jboss.netty.epollBugWorkaround", "write"; // needed by lucene SPI currently permission java.lang.RuntimePermission "getClassLoader"; diff --git a/core/src/test/java/org/elasticsearch/benchmark/mapping/ManyMappingsBenchmark.java b/core/src/test/java/org/elasticsearch/benchmark/mapping/ManyMappingsBenchmark.java index 840c3c1dc67..ff7d0840a2b 100644 --- a/core/src/test/java/org/elasticsearch/benchmark/mapping/ManyMappingsBenchmark.java +++ b/core/src/test/java/org/elasticsearch/benchmark/mapping/ManyMappingsBenchmark.java @@ -23,6 +23,7 @@ import org.elasticsearch.action.bulk.BulkRequestBuilder; import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.bootstrap.BootstrapForTesting; import org.elasticsearch.client.Client; +import org.elasticsearch.common.SuppressForbidden; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.XContentBuilder; @@ -36,6 +37,7 @@ import static org.elasticsearch.node.NodeBuilder.nodeBuilder; /** */ +@SuppressForbidden(reason = "not really source code or a test") public class ManyMappingsBenchmark { private static final String MAPPING = "{\n" + diff --git a/core/src/test/java/org/elasticsearch/benchmark/monitor/os/OsProbeBenchmark.java b/core/src/test/java/org/elasticsearch/benchmark/monitor/os/OsProbeBenchmark.java index de5f0410726..6788490f92a 100644 --- a/core/src/test/java/org/elasticsearch/benchmark/monitor/os/OsProbeBenchmark.java +++ b/core/src/test/java/org/elasticsearch/benchmark/monitor/os/OsProbeBenchmark.java @@ -19,10 +19,12 @@ package org.elasticsearch.benchmark.monitor.os; +import org.elasticsearch.common.SuppressForbidden; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.logging.ESLoggerFactory; import org.elasticsearch.monitor.os.OsProbe; +@SuppressForbidden(reason = "not really source code or a test") public class OsProbeBenchmark { private static final int ITERATIONS = 100_000; diff --git a/core/src/test/java/org/elasticsearch/benchmark/recovery/ReplicaRecoveryBenchmark.java b/core/src/test/java/org/elasticsearch/benchmark/recovery/ReplicaRecoveryBenchmark.java index 555a3326a04..b857e4d59ee 100644 --- a/core/src/test/java/org/elasticsearch/benchmark/recovery/ReplicaRecoveryBenchmark.java +++ b/core/src/test/java/org/elasticsearch/benchmark/recovery/ReplicaRecoveryBenchmark.java @@ -23,6 +23,7 @@ import org.elasticsearch.bootstrap.BootstrapForTesting; import org.elasticsearch.client.Client; import org.elasticsearch.cluster.metadata.IndexMetaData; import org.elasticsearch.cluster.routing.allocation.decider.DiskThresholdDecider; +import org.elasticsearch.common.SuppressForbidden; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.logging.ESLoggerFactory; import org.elasticsearch.common.settings.Settings; @@ -46,6 +47,7 @@ import static org.elasticsearch.node.NodeBuilder.nodeBuilder; /** * */ +@SuppressForbidden(reason = "not really source code or a test") public class ReplicaRecoveryBenchmark { private static final String INDEX_NAME = "index"; diff --git a/core/src/test/java/org/elasticsearch/benchmark/search/aggregations/GlobalOrdinalsBenchmark.java b/core/src/test/java/org/elasticsearch/benchmark/search/aggregations/GlobalOrdinalsBenchmark.java index 3eb45e1c623..ed94397068e 100644 --- a/core/src/test/java/org/elasticsearch/benchmark/search/aggregations/GlobalOrdinalsBenchmark.java +++ b/core/src/test/java/org/elasticsearch/benchmark/search/aggregations/GlobalOrdinalsBenchmark.java @@ -29,6 +29,7 @@ import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.benchmark.search.aggregations.TermsAggregationSearchBenchmark.StatsResult; import org.elasticsearch.bootstrap.BootstrapForTesting; import org.elasticsearch.client.Client; +import org.elasticsearch.common.SuppressForbidden; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.ByteSizeValue; import org.elasticsearch.common.unit.SizeValue; @@ -51,6 +52,7 @@ import static org.elasticsearch.node.NodeBuilder.nodeBuilder; /** * */ +@SuppressForbidden(reason = "not really source code or a test") public class GlobalOrdinalsBenchmark { private static final String INDEX_NAME = "index"; diff --git a/core/src/test/java/org/elasticsearch/bootstrap/JarHellTests.java b/core/src/test/java/org/elasticsearch/bootstrap/JarHellTests.java index 14a66128eda..984b9846b15 100644 --- a/core/src/test/java/org/elasticsearch/bootstrap/JarHellTests.java +++ b/core/src/test/java/org/elasticsearch/bootstrap/JarHellTests.java @@ -74,18 +74,6 @@ public class JarHellTests extends ESTestCase { } } - public void testBootclasspathLeniency() throws Exception { - Path dir = createTempDir(); - String previousJavaHome = System.getProperty("java.home"); - System.setProperty("java.home", dir.toString()); - URL[] jars = {makeJar(dir, "foo.jar", null, "DuplicateClass.class"), makeJar(dir, "bar.jar", null, "DuplicateClass.class")}; - try { - JarHell.checkJarHell(jars); - } finally { - System.setProperty("java.home", previousJavaHome); - } - } - public void testDuplicateClasspathLeniency() throws Exception { Path dir = createTempDir(); URL jar = makeJar(dir, "foo.jar", null, "Foo.class"); @@ -179,40 +167,6 @@ public class JarHellTests extends ESTestCase { } } - public void testRequiredJDKVersionIsOK() throws Exception { - Path dir = createTempDir(); - String previousJavaVersion = System.getProperty("java.specification.version"); - System.setProperty("java.specification.version", "1.7"); - - Manifest manifest = new Manifest(); - Attributes attributes = manifest.getMainAttributes(); - attributes.put(Attributes.Name.MANIFEST_VERSION, "1.0.0"); - attributes.put(new Attributes.Name("X-Compile-Target-JDK"), "1.7"); - URL[] jars = {makeJar(dir, "foo.jar", manifest, "Foo.class")}; - try { - JarHell.checkJarHell(jars); - } finally { - System.setProperty("java.specification.version", previousJavaVersion); - } - } - - public void testBadJDKVersionProperty() throws Exception { - Path dir = createTempDir(); - String previousJavaVersion = System.getProperty("java.specification.version"); - System.setProperty("java.specification.version", "bogus"); - - Manifest manifest = new Manifest(); - Attributes attributes = manifest.getMainAttributes(); - attributes.put(Attributes.Name.MANIFEST_VERSION, "1.0.0"); - attributes.put(new Attributes.Name("X-Compile-Target-JDK"), "1.7"); - URL[] jars = {makeJar(dir, "foo.jar", manifest, "Foo.class")}; - try { - JarHell.checkJarHell(jars); - } finally { - System.setProperty("java.specification.version", previousJavaVersion); - } - } - public void testBadJDKVersionInJar() throws Exception { Path dir = createTempDir(); Manifest manifest = new Manifest(); diff --git a/core/src/test/java/org/elasticsearch/bootstrap/SecurityTests.java b/core/src/test/java/org/elasticsearch/bootstrap/SecurityTests.java index d0685b1a6ce..132e46c7b90 100644 --- a/core/src/test/java/org/elasticsearch/bootstrap/SecurityTests.java +++ b/core/src/test/java/org/elasticsearch/bootstrap/SecurityTests.java @@ -19,119 +19,14 @@ package org.elasticsearch.bootstrap; -import org.apache.lucene.util.Constants; -import org.elasticsearch.common.io.PathUtils; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.env.Environment; import org.elasticsearch.test.ESTestCase; -import java.io.FilePermission; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.security.PermissionCollection; -import java.security.Permissions; -import java.util.Set; public class SecurityTests extends ESTestCase { - /** test generated permissions */ - public void testGeneratedPermissions() throws Exception { - Path path = createTempDir(); - // make a fake ES home and ensure we only grant permissions to that. - Path esHome = path.resolve("esHome"); - Settings.Builder settingsBuilder = Settings.builder(); - settingsBuilder.put("path.home", esHome.toString()); - Settings settings = settingsBuilder.build(); - - Path fakeTmpDir = createTempDir(); - String realTmpDir = System.getProperty("java.io.tmpdir"); - Permissions permissions; - try { - System.setProperty("java.io.tmpdir", fakeTmpDir.toString()); - Environment environment = new Environment(settings); - permissions = Security.createPermissions(environment); - } finally { - System.setProperty("java.io.tmpdir", realTmpDir); - } - - // the fake es home - assertNoPermissions(esHome, permissions); - // its parent - assertNoPermissions(esHome.getParent(), permissions); - // some other sibling - assertNoPermissions(esHome.getParent().resolve("other"), permissions); - // double check we overwrote java.io.tmpdir correctly for the test - assertNoPermissions(PathUtils.get(realTmpDir), permissions); - } - - /** test generated permissions for all configured paths */ - public void testEnvironmentPaths() throws Exception { - Path path = createTempDir(); - // make a fake ES home and ensure we only grant permissions to that. - Path esHome = path.resolve("esHome"); - - Settings.Builder settingsBuilder = Settings.builder(); - settingsBuilder.put("path.home", esHome.resolve("home").toString()); - settingsBuilder.put("path.conf", esHome.resolve("conf").toString()); - settingsBuilder.put("path.scripts", esHome.resolve("scripts").toString()); - settingsBuilder.put("path.plugins", esHome.resolve("plugins").toString()); - settingsBuilder.putArray("path.data", esHome.resolve("data1").toString(), esHome.resolve("data2").toString()); - settingsBuilder.put("path.shared_data", esHome.resolve("custom").toString()); - settingsBuilder.put("path.logs", esHome.resolve("logs").toString()); - settingsBuilder.put("pidfile", esHome.resolve("test.pid").toString()); - Settings settings = settingsBuilder.build(); - - Path fakeTmpDir = createTempDir(); - String realTmpDir = System.getProperty("java.io.tmpdir"); - Permissions permissions; - Environment environment; - try { - System.setProperty("java.io.tmpdir", fakeTmpDir.toString()); - environment = new Environment(settings); - permissions = Security.createPermissions(environment); - } finally { - System.setProperty("java.io.tmpdir", realTmpDir); - } - - // the fake es home - assertNoPermissions(esHome, permissions); - // its parent - assertNoPermissions(esHome.getParent(), permissions); - // some other sibling - assertNoPermissions(esHome.getParent().resolve("other"), permissions); - // double check we overwrote java.io.tmpdir correctly for the test - assertNoPermissions(PathUtils.get(realTmpDir), permissions); - - // check that all directories got permissions: - - // bin file: ro - assertExactPermissions(new FilePermission(environment.binFile().toString(), "read,readlink"), permissions); - // lib file: ro - assertExactPermissions(new FilePermission(environment.libFile().toString(), "read,readlink"), permissions); - // config file: ro - assertExactPermissions(new FilePermission(environment.configFile().toString(), "read,readlink"), permissions); - // scripts file: ro - assertExactPermissions(new FilePermission(environment.scriptsFile().toString(), "read,readlink"), permissions); - // plugins: ro - assertExactPermissions(new FilePermission(environment.pluginsFile().toString(), "read,readlink"), permissions); - - // data paths: r/w - for (Path dataPath : environment.dataFiles()) { - assertExactPermissions(new FilePermission(dataPath.toString(), "read,readlink,write,delete"), permissions); - } - for (Path dataPath : environment.dataWithClusterFiles()) { - assertExactPermissions(new FilePermission(dataPath.toString(), "read,readlink,write,delete"), permissions); - } - assertExactPermissions(new FilePermission(environment.sharedDataFile().toString(), "read,readlink,write,delete"), permissions); - // logs: r/w - assertExactPermissions(new FilePermission(environment.logsFile().toString(), "read,readlink,write,delete"), permissions); - // temp dir: r/w - assertExactPermissions(new FilePermission(fakeTmpDir.toString(), "read,readlink,write,delete"), permissions); - // PID file: delete only (for the shutdown hook) - assertExactPermissions(new FilePermission(environment.pidFile().toString(), "delete"), permissions); - } - public void testEnsureExists() throws IOException { Path p = createTempDir(); @@ -163,43 +58,6 @@ public class SecurityTests extends ESTestCase { } catch (IOException expected) {} } - public void testEnsureSymlink() throws IOException { - Path p = createTempDir(); - - Path exists = p.resolve("exists"); - Files.createDirectory(exists); - - // symlink - Path linkExists = p.resolve("linkExists"); - try { - Files.createSymbolicLink(linkExists, exists); - } catch (UnsupportedOperationException | IOException e) { - assumeNoException("test requires filesystem that supports symbolic links", e); - } catch (SecurityException e) { - assumeNoException("test cannot create symbolic links with security manager enabled", e); - } - Security.ensureDirectoryExists(linkExists); - Files.createTempFile(linkExists, null, null); - } - - public void testEnsureBrokenSymlink() throws IOException { - Path p = createTempDir(); - - // broken symlink - Path brokenLink = p.resolve("brokenLink"); - try { - Files.createSymbolicLink(brokenLink, p.resolve("nonexistent")); - } catch (UnsupportedOperationException | IOException e) { - assumeNoException("test requires filesystem that supports symbolic links", e); - } catch (SecurityException e) { - assumeNoException("test cannot create symbolic links with security manager enabled", e); - } - try { - Security.ensureDirectoryExists(brokenLink); - fail("didn't get expected exception"); - } catch (IOException expected) {} - } - /** can't execute processes */ public void testProcessExecution() throws Exception { assumeTrue("test requires security manager", System.getSecurityManager() != null); @@ -208,61 +66,4 @@ public class SecurityTests extends ESTestCase { fail("didn't get expected exception"); } catch (SecurityException expected) {} } - - /** When a configured dir is a symlink, test that permissions work on link target */ - public void testSymlinkPermissions() throws IOException { - // see https://github.com/elastic/elasticsearch/issues/12170 - assumeFalse("windows does not automatically grant permission to the target of symlinks", Constants.WINDOWS); - Path dir = createTempDir(); - - Path target = dir.resolve("target"); - Files.createDirectory(target); - - // symlink - Path link = dir.resolve("link"); - try { - Files.createSymbolicLink(link, target); - } catch (UnsupportedOperationException | IOException e) { - assumeNoException("test requires filesystem that supports symbolic links", e); - } catch (SecurityException e) { - assumeNoException("test cannot create symbolic links with security manager enabled", e); - } - Permissions permissions = new Permissions(); - Security.addPath(permissions, "testing", link, "read"); - assertExactPermissions(new FilePermission(link.toString(), "read"), permissions); - assertExactPermissions(new FilePermission(link.resolve("foo").toString(), "read"), permissions); - assertExactPermissions(new FilePermission(target.toString(), "read"), permissions); - assertExactPermissions(new FilePermission(target.resolve("foo").toString(), "read"), permissions); - } - - /** - * checks exact file permissions, meaning those and only those for that path. - */ - static void assertExactPermissions(FilePermission expected, PermissionCollection actual) { - String target = expected.getName(); // see javadocs - Set permissionSet = asSet(expected.getActions().split(",")); - boolean read = permissionSet.remove("read"); - boolean readlink = permissionSet.remove("readlink"); - boolean write = permissionSet.remove("write"); - boolean delete = permissionSet.remove("delete"); - boolean execute = permissionSet.remove("execute"); - assertTrue("unrecognized permission: " + permissionSet, permissionSet.isEmpty()); - assertEquals(read, actual.implies(new FilePermission(target, "read"))); - assertEquals(readlink, actual.implies(new FilePermission(target, "readlink"))); - assertEquals(write, actual.implies(new FilePermission(target, "write"))); - assertEquals(delete, actual.implies(new FilePermission(target, "delete"))); - assertEquals(execute, actual.implies(new FilePermission(target, "execute"))); - } - - /** - * checks that this path has no permissions - */ - static void assertNoPermissions(Path path, PermissionCollection actual) { - String target = path.toString(); - assertFalse(actual.implies(new FilePermission(target, "read"))); - assertFalse(actual.implies(new FilePermission(target, "readlink"))); - assertFalse(actual.implies(new FilePermission(target, "write"))); - assertFalse(actual.implies(new FilePermission(target, "delete"))); - assertFalse(actual.implies(new FilePermission(target, "execute"))); - } } diff --git a/core/src/test/java/org/elasticsearch/common/settings/SettingsTests.java b/core/src/test/java/org/elasticsearch/common/settings/SettingsTests.java index 8cc861a7e0f..e3f2bc1bb2b 100644 --- a/core/src/test/java/org/elasticsearch/common/settings/SettingsTests.java +++ b/core/src/test/java/org/elasticsearch/common/settings/SettingsTests.java @@ -67,25 +67,23 @@ public class SettingsTests extends ESTestCase { } public void testReplacePropertiesPlaceholderSystemProperty() { - System.setProperty("sysProp1", "sysVal1"); - try { - Settings settings = settingsBuilder() - .put("setting1", "${sysProp1}") - .replacePropertyPlaceholders() - .build(); - assertThat(settings.get("setting1"), equalTo("sysVal1")); - } finally { - System.clearProperty("sysProp1"); - } - + String value = System.getProperty("java.home"); + assertFalse(value.isEmpty()); Settings settings = settingsBuilder() - .put("setting1", "${sysProp1:defaultVal1}") + .put("setting1", "${java.home}") + .replacePropertyPlaceholders() + .build(); + assertThat(settings.get("setting1"), equalTo(value)); + + assertNull(System.getProperty("_test_property_should_not_exist")); + settings = settingsBuilder() + .put("setting1", "${_test_property_should_not_exist:defaultVal1}") .replacePropertyPlaceholders() .build(); assertThat(settings.get("setting1"), equalTo("defaultVal1")); settings = settingsBuilder() - .put("setting1", "${sysProp1:}") + .put("setting1", "${_test_property_should_not_exist:}") .replacePropertyPlaceholders() .build(); assertThat(settings.get("setting1"), is(nullValue())); diff --git a/core/src/test/java/org/elasticsearch/node/internal/InternalSettingsPreparerTests.java b/core/src/test/java/org/elasticsearch/node/internal/InternalSettingsPreparerTests.java index 4cd61ebdd14..9236a16dcbd 100644 --- a/core/src/test/java/org/elasticsearch/node/internal/InternalSettingsPreparerTests.java +++ b/core/src/test/java/org/elasticsearch/node/internal/InternalSettingsPreparerTests.java @@ -22,7 +22,6 @@ package org.elasticsearch.node.internal; import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.common.cli.CliToolTestCase; import org.elasticsearch.common.cli.Terminal; -import org.elasticsearch.common.collect.Tuple; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.SettingsException; import org.elasticsearch.env.Environment; @@ -35,9 +34,7 @@ import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import static org.elasticsearch.common.settings.Settings.settingsBuilder; @@ -45,38 +42,8 @@ import static org.hamcrest.Matchers.*; public class InternalSettingsPreparerTests extends ESTestCase { - Map savedProperties = new HashMap<>(); Settings baseEnvSettings; - @Before - public void saveSettingsSystemProperties() { - // clear out any properties the settings preparer may look for - savedProperties.clear(); - for (Object propObj : System.getProperties().keySet()) { - String property = (String)propObj; - // NOTE: these prefixes are prefixes of the defaults, so both are handled here - for (String prefix : InternalSettingsPreparer.PROPERTY_PREFIXES) { - if (property.startsWith(prefix)) { - savedProperties.put(property, System.getProperty(property)); - } - } - } - String name = System.getProperty("name"); - if (name != null) { - savedProperties.put("name", name); - } - for (String property : savedProperties.keySet()) { - System.clearProperty(property); - } - } - - @After - public void restoreSettingsSystemProperties() { - for (Map.Entry property : savedProperties.entrySet()) { - System.setProperty(property.getKey(), property.getValue()); - } - } - @Before public void createBaseEnvSettings() { baseEnvSettings = settingsBuilder() @@ -93,13 +60,13 @@ public class InternalSettingsPreparerTests extends ESTestCase { Settings settings = InternalSettingsPreparer.prepareSettings(Settings.EMPTY); assertNotNull(settings.get("name")); // a name was set assertNotNull(settings.get(ClusterName.SETTING)); // a cluster name was set - assertEquals(settings.toString(), 2, settings.names().size()); + int size = settings.names().size(); Environment env = InternalSettingsPreparer.prepareEnvironment(baseEnvSettings, null); settings = env.settings(); assertNotNull(settings.get("name")); // a name was set assertNotNull(settings.get(ClusterName.SETTING)); // a cluster name was set - assertEquals(settings.toString(), 3 /* path.home is in the base settings */, settings.names().size()); + assertEquals(settings.toString(), size + 1 /* path.home is in the base settings */, settings.names().size()); String home = baseEnvSettings.get("path.home"); String configDir = env.configFile().toString(); assertTrue(configDir, configDir.startsWith(home)); @@ -112,30 +79,6 @@ public class InternalSettingsPreparerTests extends ESTestCase { assertEquals(ClusterName.DEFAULT.value(), settings.get(ClusterName.SETTING)); } - public void testIgnoreSystemProperties() { - try { - System.setProperty("es.node.zone", "foo"); - Settings settings = settingsBuilder() - .put("node.zone", "bar") - .put(baseEnvSettings) - .build(); - Environment env = InternalSettingsPreparer.prepareEnvironment(settings, null); - // Should use setting from the system property - assertThat(env.settings().get("node.zone"), equalTo("foo")); - - settings = settingsBuilder() - .put(InternalSettingsPreparer.IGNORE_SYSTEM_PROPERTIES_SETTING, true) - .put("node.zone", "bar") - .put(baseEnvSettings) - .build(); - env = InternalSettingsPreparer.prepareEnvironment(settings, null); - // Should use setting from the system property - assertThat(env.settings().get("node.zone"), equalTo("bar")); - } finally { - System.clearProperty("es.node.zone"); - } - } - public void testReplacePromptPlaceholders() { final List replacedSecretProperties = new ArrayList<>(); final List replacedTextProperties = new ArrayList<>(); @@ -205,74 +148,6 @@ public class InternalSettingsPreparerTests extends ESTestCase { } } - public void testNameSettingsPreference() { - try { - System.setProperty("name", "sys-prop-name"); - // Test system property overrides node.name - Settings settings = settingsBuilder() - .put("node.name", "node-name") - .put(baseEnvSettings) - .build(); - Environment env = InternalSettingsPreparer.prepareEnvironment(settings, null); - assertThat(env.settings().get("name"), equalTo("sys-prop-name")); - - // test name in settings overrides sys prop and node.name - settings = settingsBuilder() - .put("name", "name-in-settings") - .put("node.name", "node-name") - .put(baseEnvSettings) - .build(); - env = InternalSettingsPreparer.prepareEnvironment(settings, null); - assertThat(env.settings().get("name"), equalTo("name-in-settings")); - - // test only node.name in settings - System.clearProperty("name"); - settings = settingsBuilder() - .put("node.name", "node-name") - .put(baseEnvSettings) - .build(); - env = InternalSettingsPreparer.prepareEnvironment(settings, null); - assertThat(env.settings().get("name"), equalTo("node-name")); - - // test no name at all results in name being set - env = InternalSettingsPreparer.prepareEnvironment(baseEnvSettings, null); - assertThat(env.settings().get("name"), not("name-in-settings")); - assertThat(env.settings().get("name"), not("sys-prop-name")); - assertThat(env.settings().get("name"), not("node-name")); - assertThat(env.settings().get("name"), notNullValue()); - } finally { - System.clearProperty("name"); - } - } - - public void testPromptForNodeNameOnlyPromptsOnce() { - final AtomicInteger counter = new AtomicInteger(); - final Terminal terminal = new CliToolTestCase.MockTerminal() { - @Override - public char[] readSecret(String message, Object... args) { - fail("readSecret should never be called by this test"); - return null; - } - - @Override - public String readText(String message, Object... args) { - int count = counter.getAndIncrement(); - return "prompted name " + count; - } - }; - - System.clearProperty("name"); - Settings settings = Settings.builder() - .put(baseEnvSettings) - .put("node.name", InternalSettingsPreparer.TEXT_PROMPT_VALUE) - .build(); - Environment env = InternalSettingsPreparer.prepareEnvironment(settings, terminal); - settings = env.settings(); - assertThat(counter.intValue(), is(1)); - assertThat(settings.get("name"), is("prompted name 0")); - assertThat(settings.get("node.name"), is("prompted name 0")); - } - public void testGarbageIsNotSwallowed() throws IOException { try { InputStream garbage = getClass().getResourceAsStream("/config/garbage/garbage.yml"); diff --git a/plugins/discovery-ec2/src/test/java/org/elasticsearch/cloud/aws/AbstractAwsTestCase.java b/plugins/discovery-ec2/src/test/java/org/elasticsearch/cloud/aws/AbstractAwsTestCase.java index 47647e17333..ec9155c51b3 100644 --- a/plugins/discovery-ec2/src/test/java/org/elasticsearch/cloud/aws/AbstractAwsTestCase.java +++ b/plugins/discovery-ec2/src/test/java/org/elasticsearch/cloud/aws/AbstractAwsTestCase.java @@ -26,11 +26,6 @@ import org.elasticsearch.common.settings.SettingsException; import org.elasticsearch.plugin.discovery.ec2.Ec2DiscoveryPlugin; import org.elasticsearch.test.ESIntegTestCase; import org.elasticsearch.test.ESIntegTestCase.ThirdParty; -import org.junit.After; -import org.junit.Before; - -import java.util.HashMap; -import java.util.Map; /** * Base class for AWS tests that require credentials. @@ -41,35 +36,6 @@ import java.util.Map; @ThirdParty public abstract class AbstractAwsTestCase extends ESIntegTestCase { - /** - * Those properties are set by the AWS SDK v1.9.4 and if not ignored, - * lead to tests failure (see AbstractRandomizedTest#IGNORED_INVARIANT_PROPERTIES) - */ - private static final String[] AWS_INVARIANT_PROPERTIES = { - "com.sun.org.apache.xml.internal.dtm.DTMManager", - "javax.xml.parsers.DocumentBuilderFactory" - }; - - private Map properties = new HashMap<>(); - - @Before - public void saveProperties() { - for (String p : AWS_INVARIANT_PROPERTIES) { - properties.put(p, System.getProperty(p)); - } - } - - @After - public void restoreProperties() { - for (String p : AWS_INVARIANT_PROPERTIES) { - if (properties.get(p) != null) { - System.setProperty(p, properties.get(p)); - } else { - System.clearProperty(p); - } - } - } - @Override protected Settings nodeSettings(int nodeOrdinal) { Settings.Builder settings = Settings.builder() diff --git a/plugins/lang-python/src/test/java/org/elasticsearch/script/python/PythonScriptEngineTests.java b/plugins/lang-python/src/test/java/org/elasticsearch/script/python/PythonScriptEngineTests.java index 35691357f34..e713bd67c92 100644 --- a/plugins/lang-python/src/test/java/org/elasticsearch/script/python/PythonScriptEngineTests.java +++ b/plugins/lang-python/src/test/java/org/elasticsearch/script/python/PythonScriptEngineTests.java @@ -48,9 +48,6 @@ public class PythonScriptEngineTests extends ESTestCase { @After public void close() { - // We need to clear some system properties - System.clearProperty("python.cachedir.skip"); - System.clearProperty("python.console.encoding"); se.close(); } diff --git a/plugins/lang-python/src/test/java/org/elasticsearch/script/python/PythonScriptMultiThreadedTests.java b/plugins/lang-python/src/test/java/org/elasticsearch/script/python/PythonScriptMultiThreadedTests.java index f0d68955614..7b9663f6b6a 100644 --- a/plugins/lang-python/src/test/java/org/elasticsearch/script/python/PythonScriptMultiThreadedTests.java +++ b/plugins/lang-python/src/test/java/org/elasticsearch/script/python/PythonScriptMultiThreadedTests.java @@ -24,7 +24,6 @@ import org.elasticsearch.script.CompiledScript; import org.elasticsearch.script.ExecutableScript; import org.elasticsearch.script.ScriptService; import org.elasticsearch.test.ESTestCase; -import org.junit.After; import java.util.HashMap; import java.util.Map; @@ -39,12 +38,6 @@ import static org.hamcrest.Matchers.equalTo; * */ public class PythonScriptMultiThreadedTests extends ESTestCase { - @After - public void close() { - // We need to clear some system properties - System.clearProperty("python.cachedir.skip"); - System.clearProperty("python.console.encoding"); - } public void testExecutableNoRuntimeParams() throws Exception { final PythonScriptEngineService se = new PythonScriptEngineService(Settings.Builder.EMPTY_SETTINGS); diff --git a/plugins/lang-python/src/test/java/org/elasticsearch/script/python/PythonSecurityTests.java b/plugins/lang-python/src/test/java/org/elasticsearch/script/python/PythonSecurityTests.java index c4a80a41916..dd25db815ac 100644 --- a/plugins/lang-python/src/test/java/org/elasticsearch/script/python/PythonSecurityTests.java +++ b/plugins/lang-python/src/test/java/org/elasticsearch/script/python/PythonSecurityTests.java @@ -45,9 +45,6 @@ public class PythonSecurityTests extends ESTestCase { @Override public void tearDown() throws Exception { - // We need to clear some system properties - System.clearProperty("python.cachedir.skip"); - System.clearProperty("python.console.encoding"); se.close(); super.tearDown(); } diff --git a/plugins/mapper-attachments/src/test/java/org/elasticsearch/mapper/attachments/StandaloneRunner.java b/plugins/mapper-attachments/src/test/java/org/elasticsearch/mapper/attachments/StandaloneRunner.java index 80de4d91d15..5aa92541437 100644 --- a/plugins/mapper-attachments/src/test/java/org/elasticsearch/mapper/attachments/StandaloneRunner.java +++ b/plugins/mapper-attachments/src/test/java/org/elasticsearch/mapper/attachments/StandaloneRunner.java @@ -20,6 +20,7 @@ package org.elasticsearch.mapper.attachments; import org.apache.commons.cli.CommandLine; +import org.elasticsearch.common.SuppressForbidden; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.cli.CliTool; import org.elasticsearch.common.cli.CliToolConfig; @@ -59,6 +60,7 @@ import static org.elasticsearch.test.StreamsUtils.copyToStringFromClasspath; * StandaloneRunner -u /tmp/mydoc.pdf * StandaloneRunner -u /tmp/mydoc.pdf --size 1000000 */ +@SuppressForbidden(reason = "commandline tool") public class StandaloneRunner extends CliTool { private static final CliToolConfig CONFIG = CliToolConfig.config("tika", StandaloneRunner.class) diff --git a/plugins/mapper-attachments/src/test/java/org/elasticsearch/mapper/attachments/VariousDocTests.java b/plugins/mapper-attachments/src/test/java/org/elasticsearch/mapper/attachments/VariousDocTests.java index 88c15c10c54..1793047ebb9 100644 --- a/plugins/mapper-attachments/src/test/java/org/elasticsearch/mapper/attachments/VariousDocTests.java +++ b/plugins/mapper-attachments/src/test/java/org/elasticsearch/mapper/attachments/VariousDocTests.java @@ -68,8 +68,6 @@ public class VariousDocTests extends AttachmentUnitTestCase { */ public void testEncryptedPDFDocument() throws Exception { assertException("encrypted.pdf", "is encrypted"); - // TODO Remove when this will be fixed in Tika. See https://issues.apache.org/jira/browse/TIKA-1548 - System.clearProperty("sun.font.fontmanager"); testMapper("encrypted.pdf", true); } diff --git a/plugins/repository-s3/src/test/java/org/elasticsearch/cloud/aws/AbstractAwsTestCase.java b/plugins/repository-s3/src/test/java/org/elasticsearch/cloud/aws/AbstractAwsTestCase.java index 9a49c674cd8..e823e8e6681 100644 --- a/plugins/repository-s3/src/test/java/org/elasticsearch/cloud/aws/AbstractAwsTestCase.java +++ b/plugins/repository-s3/src/test/java/org/elasticsearch/cloud/aws/AbstractAwsTestCase.java @@ -26,11 +26,6 @@ import org.elasticsearch.common.settings.SettingsException; import org.elasticsearch.plugin.repository.s3.S3RepositoryPlugin; import org.elasticsearch.test.ESIntegTestCase; import org.elasticsearch.test.ESIntegTestCase.ThirdParty; -import org.junit.After; -import org.junit.Before; - -import java.util.HashMap; -import java.util.Map; /** * Base class for AWS tests that require credentials. @@ -41,35 +36,6 @@ import java.util.Map; @ThirdParty public abstract class AbstractAwsTestCase extends ESIntegTestCase { - /** - * Those properties are set by the AWS SDK v1.9.4 and if not ignored, - * lead to tests failure (see AbstractRandomizedTest#IGNORED_INVARIANT_PROPERTIES) - */ - private static final String[] AWS_INVARIANT_PROPERTIES = { - "com.sun.org.apache.xml.internal.dtm.DTMManager", - "javax.xml.parsers.DocumentBuilderFactory" - }; - - private Map properties = new HashMap<>(); - - @Before - public void saveProperties() { - for (String p : AWS_INVARIANT_PROPERTIES) { - properties.put(p, System.getProperty(p)); - } - } - - @After - public void restoreProperties() { - for (String p : AWS_INVARIANT_PROPERTIES) { - if (properties.get(p) != null) { - System.setProperty(p, properties.get(p)); - } else { - System.clearProperty(p); - } - } - } - @Override protected Settings nodeSettings(int nodeOrdinal) { Settings.Builder settings = Settings.builder() diff --git a/core/src/test/java/org/elasticsearch/bootstrap/BootstrapCliParserTests.java b/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/BootstrapCliParserTests.java similarity index 98% rename from core/src/test/java/org/elasticsearch/bootstrap/BootstrapCliParserTests.java rename to qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/BootstrapCliParserTests.java index 567a664e2f8..9faa604a18e 100644 --- a/core/src/test/java/org/elasticsearch/bootstrap/BootstrapCliParserTests.java +++ b/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/BootstrapCliParserTests.java @@ -21,6 +21,7 @@ package org.elasticsearch.bootstrap; import org.elasticsearch.Build; import org.elasticsearch.Version; +import org.elasticsearch.common.SuppressForbidden; import org.elasticsearch.common.cli.CliTool.ExitStatus; import org.elasticsearch.common.cli.CliToolTestCase; import org.elasticsearch.common.collect.Tuple; @@ -36,6 +37,7 @@ import java.util.Locale; import static org.elasticsearch.common.cli.CliTool.ExitStatus.*; import static org.hamcrest.Matchers.*; +@SuppressForbidden(reason = "modifies system properties intentionally") public class BootstrapCliParserTests extends CliToolTestCase { private CaptureOutputTerminal terminal = new CaptureOutputTerminal(); diff --git a/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/EvilJarHellTests.java b/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/EvilJarHellTests.java new file mode 100644 index 00000000000..25bf3ac48f9 --- /dev/null +++ b/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/EvilJarHellTests.java @@ -0,0 +1,100 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.bootstrap; + +import org.elasticsearch.common.SuppressForbidden; +import org.elasticsearch.test.ESTestCase; + +import java.io.IOException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.util.jar.Attributes; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +/** Tests for Jarhell that change very important system properties... very evil! */ +@SuppressForbidden(reason = "modifies system properties intentionally") +public class EvilJarHellTests extends ESTestCase { + + URL makeJar(Path dir, String name, Manifest manifest, String... files) throws IOException { + Path jarpath = dir.resolve(name); + ZipOutputStream out; + if (manifest == null) { + out = new JarOutputStream(Files.newOutputStream(jarpath, StandardOpenOption.CREATE)); + } else { + out = new JarOutputStream(Files.newOutputStream(jarpath, StandardOpenOption.CREATE), manifest); + } + for (String file : files) { + out.putNextEntry(new ZipEntry(file)); + } + out.close(); + return jarpath.toUri().toURL(); + } + + public void testBootclasspathLeniency() throws Exception { + Path dir = createTempDir(); + String previousJavaHome = System.getProperty("java.home"); + System.setProperty("java.home", dir.toString()); + URL[] jars = {makeJar(dir, "foo.jar", null, "DuplicateClass.class"), makeJar(dir, "bar.jar", null, "DuplicateClass.class")}; + try { + JarHell.checkJarHell(jars); + } finally { + System.setProperty("java.home", previousJavaHome); + } + } + + public void testRequiredJDKVersionIsOK() throws Exception { + Path dir = createTempDir(); + String previousJavaVersion = System.getProperty("java.specification.version"); + System.setProperty("java.specification.version", "1.7"); + + Manifest manifest = new Manifest(); + Attributes attributes = manifest.getMainAttributes(); + attributes.put(Attributes.Name.MANIFEST_VERSION, "1.0.0"); + attributes.put(new Attributes.Name("X-Compile-Target-JDK"), "1.7"); + URL[] jars = {makeJar(dir, "foo.jar", manifest, "Foo.class")}; + try { + JarHell.checkJarHell(jars); + } finally { + System.setProperty("java.specification.version", previousJavaVersion); + } + } + + public void testBadJDKVersionProperty() throws Exception { + Path dir = createTempDir(); + String previousJavaVersion = System.getProperty("java.specification.version"); + System.setProperty("java.specification.version", "bogus"); + + Manifest manifest = new Manifest(); + Attributes attributes = manifest.getMainAttributes(); + attributes.put(Attributes.Name.MANIFEST_VERSION, "1.0.0"); + attributes.put(new Attributes.Name("X-Compile-Target-JDK"), "1.7"); + URL[] jars = {makeJar(dir, "foo.jar", manifest, "Foo.class")}; + try { + JarHell.checkJarHell(jars); + } finally { + System.setProperty("java.specification.version", previousJavaVersion); + } + } +} diff --git a/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/EvilSecurityTests.java b/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/EvilSecurityTests.java new file mode 100644 index 00000000000..20ef464e83b --- /dev/null +++ b/qa/evil-tests/src/test/java/org/elasticsearch/bootstrap/EvilSecurityTests.java @@ -0,0 +1,230 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.bootstrap; + +import org.apache.lucene.util.Constants; +import org.elasticsearch.common.SuppressForbidden; +import org.elasticsearch.common.io.PathUtils; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.env.Environment; +import org.elasticsearch.test.ESTestCase; + +import java.io.FilePermission; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.PermissionCollection; +import java.security.Permissions; +import java.util.Set; + +@SuppressForbidden(reason = "modifies system properties and attempts to create symbolic links intentionally") +public class EvilSecurityTests extends ESTestCase { + + /** test generated permissions */ + public void testGeneratedPermissions() throws Exception { + Path path = createTempDir(); + // make a fake ES home and ensure we only grant permissions to that. + Path esHome = path.resolve("esHome"); + Settings.Builder settingsBuilder = Settings.builder(); + settingsBuilder.put("path.home", esHome.toString()); + Settings settings = settingsBuilder.build(); + + Path fakeTmpDir = createTempDir(); + String realTmpDir = System.getProperty("java.io.tmpdir"); + Permissions permissions; + try { + System.setProperty("java.io.tmpdir", fakeTmpDir.toString()); + Environment environment = new Environment(settings); + permissions = Security.createPermissions(environment); + } finally { + System.setProperty("java.io.tmpdir", realTmpDir); + } + + // the fake es home + assertNoPermissions(esHome, permissions); + // its parent + assertNoPermissions(esHome.getParent(), permissions); + // some other sibling + assertNoPermissions(esHome.getParent().resolve("other"), permissions); + // double check we overwrote java.io.tmpdir correctly for the test + assertNoPermissions(PathUtils.get(realTmpDir), permissions); + } + + /** test generated permissions for all configured paths */ + public void testEnvironmentPaths() throws Exception { + Path path = createTempDir(); + // make a fake ES home and ensure we only grant permissions to that. + Path esHome = path.resolve("esHome"); + + Settings.Builder settingsBuilder = Settings.builder(); + settingsBuilder.put("path.home", esHome.resolve("home").toString()); + settingsBuilder.put("path.conf", esHome.resolve("conf").toString()); + settingsBuilder.put("path.scripts", esHome.resolve("scripts").toString()); + settingsBuilder.put("path.plugins", esHome.resolve("plugins").toString()); + settingsBuilder.putArray("path.data", esHome.resolve("data1").toString(), esHome.resolve("data2").toString()); + settingsBuilder.put("path.shared_data", esHome.resolve("custom").toString()); + settingsBuilder.put("path.logs", esHome.resolve("logs").toString()); + settingsBuilder.put("pidfile", esHome.resolve("test.pid").toString()); + Settings settings = settingsBuilder.build(); + + Path fakeTmpDir = createTempDir(); + String realTmpDir = System.getProperty("java.io.tmpdir"); + Permissions permissions; + Environment environment; + try { + System.setProperty("java.io.tmpdir", fakeTmpDir.toString()); + environment = new Environment(settings); + permissions = Security.createPermissions(environment); + } finally { + System.setProperty("java.io.tmpdir", realTmpDir); + } + + // the fake es home + assertNoPermissions(esHome, permissions); + // its parent + assertNoPermissions(esHome.getParent(), permissions); + // some other sibling + assertNoPermissions(esHome.getParent().resolve("other"), permissions); + // double check we overwrote java.io.tmpdir correctly for the test + assertNoPermissions(PathUtils.get(realTmpDir), permissions); + + // check that all directories got permissions: + + // bin file: ro + assertExactPermissions(new FilePermission(environment.binFile().toString(), "read,readlink"), permissions); + // lib file: ro + assertExactPermissions(new FilePermission(environment.libFile().toString(), "read,readlink"), permissions); + // config file: ro + assertExactPermissions(new FilePermission(environment.configFile().toString(), "read,readlink"), permissions); + // scripts file: ro + assertExactPermissions(new FilePermission(environment.scriptsFile().toString(), "read,readlink"), permissions); + // plugins: ro + assertExactPermissions(new FilePermission(environment.pluginsFile().toString(), "read,readlink"), permissions); + + // data paths: r/w + for (Path dataPath : environment.dataFiles()) { + assertExactPermissions(new FilePermission(dataPath.toString(), "read,readlink,write,delete"), permissions); + } + for (Path dataPath : environment.dataWithClusterFiles()) { + assertExactPermissions(new FilePermission(dataPath.toString(), "read,readlink,write,delete"), permissions); + } + assertExactPermissions(new FilePermission(environment.sharedDataFile().toString(), "read,readlink,write,delete"), permissions); + // logs: r/w + assertExactPermissions(new FilePermission(environment.logsFile().toString(), "read,readlink,write,delete"), permissions); + // temp dir: r/w + assertExactPermissions(new FilePermission(fakeTmpDir.toString(), "read,readlink,write,delete"), permissions); + // PID file: delete only (for the shutdown hook) + assertExactPermissions(new FilePermission(environment.pidFile().toString(), "delete"), permissions); + } + + public void testEnsureSymlink() throws IOException { + Path p = createTempDir(); + + Path exists = p.resolve("exists"); + Files.createDirectory(exists); + + // symlink + Path linkExists = p.resolve("linkExists"); + try { + Files.createSymbolicLink(linkExists, exists); + } catch (UnsupportedOperationException | IOException e) { + assumeNoException("test requires filesystem that supports symbolic links", e); + } catch (SecurityException e) { + assumeNoException("test cannot create symbolic links with security manager enabled", e); + } + Security.ensureDirectoryExists(linkExists); + Files.createTempFile(linkExists, null, null); + } + + public void testEnsureBrokenSymlink() throws IOException { + Path p = createTempDir(); + + // broken symlink + Path brokenLink = p.resolve("brokenLink"); + try { + Files.createSymbolicLink(brokenLink, p.resolve("nonexistent")); + } catch (UnsupportedOperationException | IOException e) { + assumeNoException("test requires filesystem that supports symbolic links", e); + } catch (SecurityException e) { + assumeNoException("test cannot create symbolic links with security manager enabled", e); + } + try { + Security.ensureDirectoryExists(brokenLink); + fail("didn't get expected exception"); + } catch (IOException expected) {} + } + + /** When a configured dir is a symlink, test that permissions work on link target */ + public void testSymlinkPermissions() throws IOException { + // see https://github.com/elastic/elasticsearch/issues/12170 + assumeFalse("windows does not automatically grant permission to the target of symlinks", Constants.WINDOWS); + Path dir = createTempDir(); + + Path target = dir.resolve("target"); + Files.createDirectory(target); + + // symlink + Path link = dir.resolve("link"); + try { + Files.createSymbolicLink(link, target); + } catch (UnsupportedOperationException | IOException e) { + assumeNoException("test requires filesystem that supports symbolic links", e); + } catch (SecurityException e) { + assumeNoException("test cannot create symbolic links with security manager enabled", e); + } + Permissions permissions = new Permissions(); + Security.addPath(permissions, "testing", link, "read"); + assertExactPermissions(new FilePermission(link.toString(), "read"), permissions); + assertExactPermissions(new FilePermission(link.resolve("foo").toString(), "read"), permissions); + assertExactPermissions(new FilePermission(target.toString(), "read"), permissions); + assertExactPermissions(new FilePermission(target.resolve("foo").toString(), "read"), permissions); + } + + /** + * checks exact file permissions, meaning those and only those for that path. + */ + static void assertExactPermissions(FilePermission expected, PermissionCollection actual) { + String target = expected.getName(); // see javadocs + Set permissionSet = asSet(expected.getActions().split(",")); + boolean read = permissionSet.remove("read"); + boolean readlink = permissionSet.remove("readlink"); + boolean write = permissionSet.remove("write"); + boolean delete = permissionSet.remove("delete"); + boolean execute = permissionSet.remove("execute"); + assertTrue("unrecognized permission: " + permissionSet, permissionSet.isEmpty()); + assertEquals(read, actual.implies(new FilePermission(target, "read"))); + assertEquals(readlink, actual.implies(new FilePermission(target, "readlink"))); + assertEquals(write, actual.implies(new FilePermission(target, "write"))); + assertEquals(delete, actual.implies(new FilePermission(target, "delete"))); + assertEquals(execute, actual.implies(new FilePermission(target, "execute"))); + } + + /** + * checks that this path has no permissions + */ + static void assertNoPermissions(Path path, PermissionCollection actual) { + String target = path.toString(); + assertFalse(actual.implies(new FilePermission(target, "read"))); + assertFalse(actual.implies(new FilePermission(target, "readlink"))); + assertFalse(actual.implies(new FilePermission(target, "write"))); + assertFalse(actual.implies(new FilePermission(target, "delete"))); + assertFalse(actual.implies(new FilePermission(target, "execute"))); + } +} diff --git a/core/src/test/java/org/elasticsearch/common/cli/CliToolTests.java b/qa/evil-tests/src/test/java/org/elasticsearch/common/cli/CliToolTests.java similarity index 99% rename from core/src/test/java/org/elasticsearch/common/cli/CliToolTests.java rename to qa/evil-tests/src/test/java/org/elasticsearch/common/cli/CliToolTests.java index 20fbaa0ea9f..2613ab9951a 100644 --- a/core/src/test/java/org/elasticsearch/common/cli/CliToolTests.java +++ b/qa/evil-tests/src/test/java/org/elasticsearch/common/cli/CliToolTests.java @@ -22,6 +22,7 @@ package org.elasticsearch.common.cli; import org.apache.commons.cli.CommandLine; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.common.Strings; +import org.elasticsearch.common.SuppressForbidden; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; import org.elasticsearch.node.internal.InternalSettingsPreparer; @@ -45,6 +46,7 @@ import static org.hamcrest.Matchers.is; /** * */ +@SuppressForbidden(reason = "modifies system properties intentionally") public class CliToolTests extends CliToolTestCase { public void testOK() throws Exception { Terminal terminal = new MockTerminal(); diff --git a/qa/evil-tests/src/test/java/org/elasticsearch/node/internal/EvilInternalSettingsPreparerTests.java b/qa/evil-tests/src/test/java/org/elasticsearch/node/internal/EvilInternalSettingsPreparerTests.java new file mode 100644 index 00000000000..52486ba7d62 --- /dev/null +++ b/qa/evil-tests/src/test/java/org/elasticsearch/node/internal/EvilInternalSettingsPreparerTests.java @@ -0,0 +1,145 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.elasticsearch.node.internal; + +import org.elasticsearch.common.SuppressForbidden; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.env.Environment; +import org.elasticsearch.test.ESTestCase; +import org.junit.After; +import org.junit.Before; + +import java.util.HashMap; +import java.util.Map; + +import static org.elasticsearch.common.settings.Settings.settingsBuilder; +import static org.hamcrest.Matchers.*; + +@SuppressForbidden(reason = "modifies system properties intentionally") +public class EvilInternalSettingsPreparerTests extends ESTestCase { + + Map savedProperties = new HashMap<>(); + Settings baseEnvSettings; + + @Before + public void saveSettingsSystemProperties() { + // clear out any properties the settings preparer may look for + savedProperties.clear(); + for (Object propObj : System.getProperties().keySet()) { + String property = (String)propObj; + // NOTE: these prefixes are prefixes of the defaults, so both are handled here + for (String prefix : InternalSettingsPreparer.PROPERTY_PREFIXES) { + if (property.startsWith(prefix)) { + savedProperties.put(property, System.getProperty(property)); + } + } + } + String name = System.getProperty("name"); + if (name != null) { + savedProperties.put("name", name); + } + for (String property : savedProperties.keySet()) { + System.clearProperty(property); + } + } + + @After + public void restoreSettingsSystemProperties() { + for (Map.Entry property : savedProperties.entrySet()) { + System.setProperty(property.getKey(), property.getValue()); + } + } + + @Before + public void createBaseEnvSettings() { + baseEnvSettings = settingsBuilder() + .put("path.home", createTempDir()) + .build(); + } + + @After + public void clearBaseEnvSettings() { + baseEnvSettings = null; + } + + public void testIgnoreSystemProperties() { + try { + System.setProperty("es.node.zone", "foo"); + Settings settings = settingsBuilder() + .put("node.zone", "bar") + .put(baseEnvSettings) + .build(); + Environment env = InternalSettingsPreparer.prepareEnvironment(settings, null); + // Should use setting from the system property + assertThat(env.settings().get("node.zone"), equalTo("foo")); + + settings = settingsBuilder() + .put(InternalSettingsPreparer.IGNORE_SYSTEM_PROPERTIES_SETTING, true) + .put("node.zone", "bar") + .put(baseEnvSettings) + .build(); + env = InternalSettingsPreparer.prepareEnvironment(settings, null); + // Should use setting from the system property + assertThat(env.settings().get("node.zone"), equalTo("bar")); + } finally { + System.clearProperty("es.node.zone"); + } + } + + public void testNameSettingsPreference() { + try { + System.setProperty("name", "sys-prop-name"); + // Test system property overrides node.name + Settings settings = settingsBuilder() + .put("node.name", "node-name") + .put(baseEnvSettings) + .build(); + Environment env = InternalSettingsPreparer.prepareEnvironment(settings, null); + assertThat(env.settings().get("name"), equalTo("sys-prop-name")); + + // test name in settings overrides sys prop and node.name + settings = settingsBuilder() + .put("name", "name-in-settings") + .put("node.name", "node-name") + .put(baseEnvSettings) + .build(); + env = InternalSettingsPreparer.prepareEnvironment(settings, null); + assertThat(env.settings().get("name"), equalTo("name-in-settings")); + + // test only node.name in settings + System.clearProperty("name"); + settings = settingsBuilder() + .put("node.name", "node-name") + .put(baseEnvSettings) + .build(); + env = InternalSettingsPreparer.prepareEnvironment(settings, null); + assertThat(env.settings().get("name"), equalTo("node-name")); + + // test no name at all results in name being set + env = InternalSettingsPreparer.prepareEnvironment(baseEnvSettings, null); + assertThat(env.settings().get("name"), not("name-in-settings")); + assertThat(env.settings().get("name"), not("sys-prop-name")); + assertThat(env.settings().get("name"), not("node-name")); + assertThat(env.settings().get("name"), notNullValue()); + } finally { + System.clearProperty("name"); + } + } +} diff --git a/qa/evil-tests/src/test/java/org/elasticsearch/plugins/PluginManagerTests.java b/qa/evil-tests/src/test/java/org/elasticsearch/plugins/PluginManagerTests.java index b6323df7931..0e7597e61e8 100644 --- a/qa/evil-tests/src/test/java/org/elasticsearch/plugins/PluginManagerTests.java +++ b/qa/evil-tests/src/test/java/org/elasticsearch/plugins/PluginManagerTests.java @@ -22,6 +22,7 @@ import org.apache.http.impl.client.HttpClients; import org.apache.lucene.util.LuceneTestCase; import org.elasticsearch.Version; import org.elasticsearch.common.Base64; +import org.elasticsearch.common.SuppressForbidden; import org.elasticsearch.common.cli.CliTool; import org.elasticsearch.common.cli.CliTool.ExitStatus; import org.elasticsearch.common.cli.CliToolTestCase.CaptureOutputTerminal; @@ -82,6 +83,7 @@ import static org.jboss.netty.handler.codec.http.HttpVersion.HTTP_1_1; @LuceneTestCase.SuppressFileSystems("*") // TODO: clean up this test to allow extra files // TODO: jimfs is really broken here (throws wrong exception from detection method). // if its in your classpath, then do not use plugins!!!!!! +@SuppressForbidden(reason = "modifies system properties intentionally") public class PluginManagerTests extends ESIntegTestCase { private Environment environment; diff --git a/core/src/test/java/org/elasticsearch/plugins/PluginManagerUnitTests.java b/qa/evil-tests/src/test/java/org/elasticsearch/plugins/PluginManagerUnitTests.java similarity index 98% rename from core/src/test/java/org/elasticsearch/plugins/PluginManagerUnitTests.java rename to qa/evil-tests/src/test/java/org/elasticsearch/plugins/PluginManagerUnitTests.java index 86cdd32344f..266b44ebfbd 100644 --- a/core/src/test/java/org/elasticsearch/plugins/PluginManagerUnitTests.java +++ b/qa/evil-tests/src/test/java/org/elasticsearch/plugins/PluginManagerUnitTests.java @@ -21,6 +21,7 @@ package org.elasticsearch.plugins; import org.elasticsearch.Build; import org.elasticsearch.Version; +import org.elasticsearch.common.SuppressForbidden; import org.elasticsearch.common.http.client.HttpDownloadHelper; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; @@ -42,6 +43,7 @@ import static org.hamcrest.Matchers.is; /** * */ +@SuppressForbidden(reason = "modifies system properties intentionally") public class PluginManagerUnitTests extends ESTestCase { @After public void cleanSystemProperty() { diff --git a/core/src/test/java/org/elasticsearch/tribe/TribeUnitTests.java b/qa/evil-tests/src/test/java/org/elasticsearch/tribe/TribeUnitTests.java similarity index 97% rename from core/src/test/java/org/elasticsearch/tribe/TribeUnitTests.java rename to qa/evil-tests/src/test/java/org/elasticsearch/tribe/TribeUnitTests.java index 96525373183..c13b91b159a 100644 --- a/core/src/test/java/org/elasticsearch/tribe/TribeUnitTests.java +++ b/qa/evil-tests/src/test/java/org/elasticsearch/tribe/TribeUnitTests.java @@ -22,6 +22,7 @@ package org.elasticsearch.tribe; import org.elasticsearch.client.Client; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.node.DiscoveryNode; +import org.elasticsearch.common.SuppressForbidden; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.node.Node; import org.elasticsearch.node.NodeBuilder; @@ -42,6 +43,7 @@ import static org.hamcrest.CoreMatchers.equalTo; * all the time, while we need to make the tribe node accept them in this case, so that we can verify that they are not read again as part * of the tribe client nodes initialization. Note that the started nodes will obey to the 'node.mode' settings as the internal cluster does. */ +@SuppressForbidden(reason = "modifies system properties intentionally") public class TribeUnitTests extends ESTestCase { private static Node tribe1; diff --git a/core/src/test/resources/org/elasticsearch/common/cli/tool-cmd1.help b/qa/evil-tests/src/test/resources/org/elasticsearch/common/cli/tool-cmd1.help similarity index 100% rename from core/src/test/resources/org/elasticsearch/common/cli/tool-cmd1.help rename to qa/evil-tests/src/test/resources/org/elasticsearch/common/cli/tool-cmd1.help diff --git a/core/src/test/resources/org/elasticsearch/common/cli/tool.help b/qa/evil-tests/src/test/resources/org/elasticsearch/common/cli/tool.help similarity index 100% rename from core/src/test/resources/org/elasticsearch/common/cli/tool.help rename to qa/evil-tests/src/test/resources/org/elasticsearch/common/cli/tool.help diff --git a/core/src/test/resources/org/elasticsearch/tribe/elasticsearch.yml b/qa/evil-tests/src/test/resources/org/elasticsearch/tribe/elasticsearch.yml similarity index 100% rename from core/src/test/resources/org/elasticsearch/tribe/elasticsearch.yml rename to qa/evil-tests/src/test/resources/org/elasticsearch/tribe/elasticsearch.yml diff --git a/test-framework/src/main/java/org/elasticsearch/bootstrap/BootstrapForTesting.java b/test-framework/src/main/java/org/elasticsearch/bootstrap/BootstrapForTesting.java index b1b5cb3f102..68784083797 100644 --- a/test-framework/src/main/java/org/elasticsearch/bootstrap/BootstrapForTesting.java +++ b/test-framework/src/main/java/org/elasticsearch/bootstrap/BootstrapForTesting.java @@ -84,6 +84,9 @@ public class BootstrapForTesting { // initialize probes Bootstrap.initializeProbes(); + // initialize sysprops + BootstrapInfo.getSystemProperties(); + // check for jar hell try { JarHell.checkJarHell(); diff --git a/test-framework/src/main/java/org/elasticsearch/common/cli/CliToolTestCase.java b/test-framework/src/main/java/org/elasticsearch/common/cli/CliToolTestCase.java index 38515ff14c9..ab304c28c54 100644 --- a/test-framework/src/main/java/org/elasticsearch/common/cli/CliToolTestCase.java +++ b/test-framework/src/main/java/org/elasticsearch/common/cli/CliToolTestCase.java @@ -21,6 +21,7 @@ package org.elasticsearch.common.cli; import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.common.Strings; +import org.elasticsearch.common.SuppressForbidden; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.StreamsUtils; import org.junit.After; @@ -40,11 +41,13 @@ import static org.hamcrest.Matchers.hasSize; public abstract class CliToolTestCase extends ESTestCase { @Before + @SuppressForbidden(reason = "sets es.default.path.home during tests") public void setPathHome() { System.setProperty("es.default.path.home", createTempDir().toString()); } @After + @SuppressForbidden(reason = "clears es.default.path.home during tests") public void clearPathHome() { System.clearProperty("es.default.path.home"); } diff --git a/test-framework/src/main/java/org/elasticsearch/test/ESTestCase.java b/test-framework/src/main/java/org/elasticsearch/test/ESTestCase.java index b0841033a99..c59c3ba4d4e 100644 --- a/test-framework/src/main/java/org/elasticsearch/test/ESTestCase.java +++ b/test-framework/src/main/java/org/elasticsearch/test/ESTestCase.java @@ -42,6 +42,7 @@ import org.elasticsearch.bootstrap.BootstrapForTesting; import org.elasticsearch.cache.recycler.MockPageCacheRecycler; import org.elasticsearch.client.Requests; import org.elasticsearch.cluster.metadata.IndexMetaData; +import org.elasticsearch.common.SuppressForbidden; import org.elasticsearch.common.io.PathUtils; import org.elasticsearch.common.io.PathUtilsForTesting; import org.elasticsearch.common.logging.ESLogger; @@ -163,6 +164,7 @@ public abstract class ESTestCase extends LuceneTestCase { // randomize and override the number of cpus so tests reproduce regardless of real number of cpus @BeforeClass + @SuppressForbidden(reason = "sets the number of cpus during tests") public static void setProcessors() { int numCpu = TestUtil.nextInt(random(), 1, 4); System.setProperty(EsExecutors.DEFAULT_SYSPROP, Integer.toString(numCpu)); @@ -170,6 +172,7 @@ public abstract class ESTestCase extends LuceneTestCase { } @AfterClass + @SuppressForbidden(reason = "clears the number of cpus during tests") public static void restoreProcessors() { System.clearProperty(EsExecutors.DEFAULT_SYSPROP); }