/* * 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.Build; import org.elasticsearch.Version; import org.elasticsearch.cli.ExitCodes; import org.elasticsearch.monitor.jvm.JvmInfo; import java.nio.file.Path; import java.util.Map; import java.util.function.Consumer; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.hasEntry; public class ElasticsearchCliTests extends ESElasticsearchCliTestCase { public void testVersion() throws Exception { runTestThatVersionIsMutuallyExclusiveToOtherOptions("-V", "-d"); runTestThatVersionIsMutuallyExclusiveToOtherOptions("-V", "--daemonize"); runTestThatVersionIsMutuallyExclusiveToOtherOptions("-V", "-p", "/tmp/pid"); runTestThatVersionIsMutuallyExclusiveToOtherOptions("-V", "--pidfile", "/tmp/pid"); runTestThatVersionIsMutuallyExclusiveToOtherOptions("--version", "-d"); runTestThatVersionIsMutuallyExclusiveToOtherOptions("--version", "--daemonize"); runTestThatVersionIsMutuallyExclusiveToOtherOptions("--version", "-p", "/tmp/pid"); runTestThatVersionIsMutuallyExclusiveToOtherOptions("--version", "--pidfile", "/tmp/pid"); runTestThatVersionIsMutuallyExclusiveToOtherOptions("--version", "-q"); runTestThatVersionIsMutuallyExclusiveToOtherOptions("--version", "--quiet"); runTestThatVersionIsReturned("-V"); runTestThatVersionIsReturned("--version"); } private void runTestThatVersionIsMutuallyExclusiveToOtherOptions(String... args) throws Exception { runTestVersion( ExitCodes.USAGE, output -> assertThat( output, allOf(containsString("ERROR:"), containsString("are unavailable given other options on the command line"))), args); } private void runTestThatVersionIsReturned(String... args) throws Exception { runTestVersion(ExitCodes.OK, output -> { assertThat(output, containsString("Version: " + Version.CURRENT.toString())); assertThat(output, containsString("Build: " + Build.CURRENT.shortHash() + "/" + Build.CURRENT.date())); assertThat(output, containsString("JVM: " + JvmInfo.jvmInfo().version())); }, args); } private void runTestVersion(int expectedStatus, Consumer<String> outputConsumer, String... args) throws Exception { runTest(expectedStatus, false, outputConsumer, (foreground, pidFile, quiet, esSettings) -> {}, args); } public void testPositionalArgs() throws Exception { runTest( ExitCodes.USAGE, false, output -> assertThat(output, containsString("Positional arguments not allowed, found [foo]")), (foreground, pidFile, quiet, esSettings) -> {}, "foo"); runTest( ExitCodes.USAGE, false, output -> assertThat(output, containsString("Positional arguments not allowed, found [foo, bar]")), (foreground, pidFile, quiet, esSettings) -> {}, "foo", "bar"); runTest( ExitCodes.USAGE, false, output -> assertThat(output, containsString("Positional arguments not allowed, found [foo]")), (foreground, pidFile, quiet, esSettings) -> {}, "-E", "foo=bar", "foo", "-E", "baz=qux"); } public void testThatPidFileCanBeConfigured() throws Exception { Path tmpDir = createTempDir(); Path pidFile = tmpDir.resolve("pid"); runPidFileTest(ExitCodes.USAGE, false, output -> assertThat(output, containsString("Option p/pidfile requires an argument")), pidFile, "-p"); runPidFileTest(ExitCodes.OK, true, output -> {}, pidFile, "-p", pidFile.toString()); runPidFileTest(ExitCodes.OK, true, output -> {}, pidFile, "--pidfile", tmpDir.toString() + "/pid"); } private void runPidFileTest(final int expectedStatus, final boolean expectedInit, Consumer<String> outputConsumer, Path expectedPidFile, final String... args) throws Exception { runTest( expectedStatus, expectedInit, outputConsumer, (foreground, pidFile, quiet, esSettings) -> assertThat(pidFile.toString(), equalTo(expectedPidFile.toString())), args); } public void testThatParsingDaemonizeWorks() throws Exception { runDaemonizeTest(true, "-d"); runDaemonizeTest(true, "--daemonize"); runDaemonizeTest(false); } private void runDaemonizeTest(final boolean expectedDaemonize, final String... args) throws Exception { runTest( ExitCodes.OK, true, output -> {}, (foreground, pidFile, quiet, esSettings) -> assertThat(foreground, equalTo(!expectedDaemonize)), args); } public void testThatParsingQuietOptionWorks() throws Exception { runQuietTest(true, "-q"); runQuietTest(true, "--quiet"); runQuietTest(false); } private void runQuietTest(final boolean expectedQuiet, final String... args) throws Exception { runTest( ExitCodes.OK, true, output -> {}, (foreground, pidFile, quiet, esSettings) -> assertThat(quiet, equalTo(expectedQuiet)), args); } public void testElasticsearchSettings() throws Exception { runTest( ExitCodes.OK, true, output -> {}, (foreground, pidFile, quiet, env) -> { Map<String, String> settings = env.settings().getAsMap(); assertThat(settings, hasEntry("foo", "bar")); assertThat(settings, hasEntry("baz", "qux")); }, "-Efoo=bar", "-E", "baz=qux"); } public void testElasticsearchSettingCanNotBeEmpty() throws Exception { runTest( ExitCodes.USAGE, false, output -> assertThat(output, containsString("setting [foo] must not be empty")), (foreground, pidFile, quiet, esSettings) -> {}, "-E", "foo="); } public void testElasticsearchSettingCanNotBeDuplicated() throws Exception { runTest( ExitCodes.USAGE, false, output -> assertThat(output, containsString("setting [foo] already set, saw [bar] and [baz]")), (foreground, pidFile, quiet, initialEnv) -> {}, "-E", "foo=bar", "-E", "foo=baz"); } public void testUnknownOption() throws Exception { runTest( ExitCodes.USAGE, false, output -> assertThat(output, containsString("network.host is not a recognized option")), (foreground, pidFile, quiet, esSettings) -> {}, "--network.host"); } }