mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-03-26 18:08:36 +00:00
Moved MockTerminal and created a base test case for cli commands.
This commit is contained in:
parent
7a49cd1287
commit
45b5ab24fe
@ -49,14 +49,14 @@ public abstract class Command {
|
||||
}
|
||||
|
||||
/** Parses options for this command from args and executes it. */
|
||||
public final int main(String[] args, Terminal terminal) throws Exception {
|
||||
protected final int main(String[] args, Terminal terminal) throws Exception {
|
||||
|
||||
final OptionSet options;
|
||||
try {
|
||||
options = parser.parse(args);
|
||||
} catch (OptionException e) {
|
||||
printHelp(terminal);
|
||||
terminal.println("ERROR: " + e.getMessage());
|
||||
terminal.println(Terminal.Verbosity.SILENT, "ERROR: " + e.getMessage());
|
||||
return ExitCodes.USAGE;
|
||||
}
|
||||
|
||||
@ -69,7 +69,7 @@ public abstract class Command {
|
||||
if (options.has(verboseOption)) {
|
||||
// mutually exclusive, we can remove this with jopt-simple 5.0, which natively supports it
|
||||
printHelp(terminal);
|
||||
terminal.println("ERROR: Cannot specify -s and -v together");
|
||||
terminal.println(Terminal.Verbosity.SILENT, "ERROR: Cannot specify -s and -v together");
|
||||
return ExitCodes.USAGE;
|
||||
}
|
||||
terminal.setVerbosity(Terminal.Verbosity.SILENT);
|
||||
|
@ -1,138 +0,0 @@
|
||||
/*
|
||||
* 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.common.cli;
|
||||
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.env.Environment;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.attribute.PosixFileAttributeView;
|
||||
import java.nio.file.attribute.PosixFileAttributes;
|
||||
import java.nio.file.attribute.PosixFilePermission;
|
||||
import java.nio.file.attribute.PosixFilePermissions;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A helper command that checks if configured paths have been changed when running a CLI command.
|
||||
* It is only executed in case of specified paths by the command and if the paths underlying filesystem
|
||||
* supports posix permissions.
|
||||
*
|
||||
* If this is the case, a warn message is issued whenever an owner, a group or the file permissions is changed by
|
||||
* the command being executed and not configured back to its prior state, which should be the task of the command
|
||||
* being executed.
|
||||
*
|
||||
*/
|
||||
public abstract class CheckFileCommand extends CliTool.Command {
|
||||
|
||||
public CheckFileCommand(Terminal terminal) {
|
||||
super(terminal);
|
||||
}
|
||||
|
||||
/**
|
||||
* abstract method, which should implement the same logic as CliTool.Command.execute(), but is wrapped
|
||||
*/
|
||||
public abstract CliTool.ExitStatus doExecute(Settings settings, Environment env) throws Exception;
|
||||
|
||||
/**
|
||||
* Returns the array of paths, that should be checked if the permissions, user or groups have changed
|
||||
* before and after execution of the command
|
||||
*
|
||||
*/
|
||||
protected abstract Path[] pathsForPermissionsCheck(Settings settings, Environment env) throws Exception;
|
||||
|
||||
@Override
|
||||
public CliTool.ExitStatus execute(Settings settings, Environment env) throws Exception {
|
||||
Path[] paths = pathsForPermissionsCheck(settings, env);
|
||||
|
||||
if (paths == null || paths.length == 0) {
|
||||
return doExecute(settings, env);
|
||||
}
|
||||
|
||||
Map<Path, Set<PosixFilePermission>> permissions = new HashMap<>(paths.length);
|
||||
Map<Path, String> owners = new HashMap<>(paths.length);
|
||||
Map<Path, String> groups = new HashMap<>(paths.length);
|
||||
|
||||
if (paths != null && paths.length > 0) {
|
||||
for (Path path : paths) {
|
||||
try {
|
||||
boolean supportsPosixPermissions = Environment.getFileStore(path).supportsFileAttributeView(PosixFileAttributeView.class);
|
||||
if (supportsPosixPermissions) {
|
||||
PosixFileAttributes attributes = Files.readAttributes(path, PosixFileAttributes.class);
|
||||
permissions.put(path, attributes.permissions());
|
||||
owners.put(path, attributes.owner().getName());
|
||||
groups.put(path, attributes.group().getName());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// silently swallow if not supported, no need to log things
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CliTool.ExitStatus status = doExecute(settings, env);
|
||||
|
||||
// check if permissions differ
|
||||
for (Map.Entry<Path, Set<PosixFilePermission>> entry : permissions.entrySet()) {
|
||||
if (!Files.exists(entry.getKey())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Set<PosixFilePermission> permissionsBeforeWrite = entry.getValue();
|
||||
Set<PosixFilePermission> permissionsAfterWrite = Files.getPosixFilePermissions(entry.getKey());
|
||||
if (!permissionsBeforeWrite.equals(permissionsAfterWrite)) {
|
||||
terminal.println(Terminal.Verbosity.SILENT, "WARNING: The file permissions of [" + entry.getKey() + "] have changed "
|
||||
+ "from [" + PosixFilePermissions.toString(permissionsBeforeWrite) + "] "
|
||||
+ "to [" + PosixFilePermissions.toString(permissionsAfterWrite) + "]");
|
||||
terminal.println(Terminal.Verbosity.SILENT, "Please ensure that the user account running Elasticsearch has read access to this file!");
|
||||
}
|
||||
}
|
||||
|
||||
// check if owner differs
|
||||
for (Map.Entry<Path, String> entry : owners.entrySet()) {
|
||||
if (!Files.exists(entry.getKey())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String ownerBeforeWrite = entry.getValue();
|
||||
String ownerAfterWrite = Files.getOwner(entry.getKey()).getName();
|
||||
if (!ownerAfterWrite.equals(ownerBeforeWrite)) {
|
||||
terminal.println(Terminal.Verbosity.SILENT, "WARNING: Owner of file [" + entry.getKey() + "] used to be [" + ownerBeforeWrite + "], but now is [" + ownerAfterWrite + "]");
|
||||
}
|
||||
}
|
||||
|
||||
// check if group differs
|
||||
for (Map.Entry<Path, String> entry : groups.entrySet()) {
|
||||
if (!Files.exists(entry.getKey())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String groupBeforeWrite = entry.getValue();
|
||||
String groupAfterWrite = Files.readAttributes(entry.getKey(), PosixFileAttributes.class).group().getName();
|
||||
if (!groupAfterWrite.equals(groupBeforeWrite)) {
|
||||
terminal.println(Terminal.Verbosity.SILENT, "WARNING: Group of file [" + entry.getKey() + "] used to be [" + groupBeforeWrite + "], but now is [" + groupAfterWrite + "]");
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
}
|
@ -19,7 +19,10 @@
|
||||
|
||||
package org.elasticsearch.common.cli;
|
||||
|
||||
public class TerminalTests extends CliToolTestCase {
|
||||
import org.elasticsearch.cli.MockTerminal;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
|
||||
public class TerminalTests extends ESTestCase {
|
||||
public void testVerbosity() throws Exception {
|
||||
MockTerminal terminal = new MockTerminal();
|
||||
terminal.setVerbosity(Terminal.Verbosity.SILENT);
|
||||
@ -48,7 +51,7 @@ public class TerminalTests extends CliToolTestCase {
|
||||
logTerminal.println(verbosity, text);
|
||||
String output = logTerminal.getOutput();
|
||||
assertTrue(output, output.contains(text));
|
||||
logTerminal.resetOutput();
|
||||
logTerminal.reset();
|
||||
}
|
||||
|
||||
private void assertNotPrinted(MockTerminal logTerminal, Terminal.Verbosity verbosity, String text) throws Exception {
|
||||
|
@ -27,7 +27,7 @@ import java.util.Arrays;
|
||||
|
||||
import org.apache.log4j.Appender;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.elasticsearch.common.cli.MockTerminal;
|
||||
import org.elasticsearch.cli.MockTerminal;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.env.Environment;
|
||||
import org.elasticsearch.node.internal.InternalSettingsPreparer;
|
||||
|
@ -24,7 +24,7 @@ import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import org.elasticsearch.common.cli.MockTerminal;
|
||||
import org.elasticsearch.cli.MockTerminal;
|
||||
import org.elasticsearch.cluster.ClusterName;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.settings.SettingsException;
|
||||
|
@ -20,10 +20,8 @@
|
||||
package org.elasticsearch.plugins;
|
||||
|
||||
import org.elasticsearch.common.cli.CliToolTestCase;
|
||||
import org.elasticsearch.common.cli.MockTerminal;
|
||||
import org.elasticsearch.cli.MockTerminal;
|
||||
|
||||
import static org.elasticsearch.common.cli.CliTool.ExitStatus.OK_AND_EXIT;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.hasItem;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
|
@ -25,7 +25,7 @@ import org.elasticsearch.common.SuppressForbidden;
|
||||
import org.elasticsearch.common.cli.CliTool.ExitStatus;
|
||||
import org.elasticsearch.common.cli.CliToolTestCase;
|
||||
import org.elasticsearch.cli.UserError;
|
||||
import org.elasticsearch.common.cli.MockTerminal;
|
||||
import org.elasticsearch.cli.MockTerminal;
|
||||
import org.elasticsearch.common.collect.Tuple;
|
||||
import org.elasticsearch.monitor.jvm.JvmInfo;
|
||||
import org.junit.After;
|
||||
@ -89,7 +89,7 @@ public class BootstrapCliParserTests extends CliToolTestCase {
|
||||
assertTrue(output, output.contains(Build.CURRENT.date()));
|
||||
assertTrue(output, output.contains(JvmInfo.jvmInfo().version()));
|
||||
|
||||
terminal.resetOutput();
|
||||
terminal.reset();
|
||||
parser = new BootstrapCLIParser(terminal);
|
||||
status = parser.execute(args("start --version"));
|
||||
assertStatus(status, OK_AND_EXIT);
|
||||
@ -177,7 +177,7 @@ public class BootstrapCliParserTests extends CliToolTestCase {
|
||||
String output = terminal.getOutput();
|
||||
assertTrue(output, output.contains("Parameter [network.host] needs value"));
|
||||
|
||||
terminal.resetOutput();
|
||||
terminal.reset();
|
||||
status = parser.execute(args("start --network.host --foo"));
|
||||
assertStatus(status, USAGE);
|
||||
output = terminal.getOutput();
|
||||
@ -194,7 +194,7 @@ public class BootstrapCliParserTests extends CliToolTestCase {
|
||||
assertTrue(output, output.contains("Unrecognized option: --unknown-param"));
|
||||
|
||||
// single dash in extra params
|
||||
terminal.resetOutput();
|
||||
terminal.reset();
|
||||
parser = new BootstrapCLIParser(terminal);
|
||||
status = parser.execute(args("start -network.host 127.0.0.1"));
|
||||
assertStatus(status, USAGE);
|
||||
@ -228,7 +228,7 @@ public class BootstrapCliParserTests extends CliToolTestCase {
|
||||
tuples.add(new Tuple<>("-h", "elasticsearch.help"));
|
||||
|
||||
for (Tuple<String, String> tuple : tuples) {
|
||||
terminal.resetOutput();
|
||||
terminal.reset();
|
||||
BootstrapCLIParser parser = new BootstrapCLIParser(terminal);
|
||||
ExitStatus status = parser.execute(args(tuple.v1()));
|
||||
assertStatus(status, OK_AND_EXIT);
|
||||
|
@ -36,7 +36,6 @@ import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.nio.file.attribute.PosixFileAttributeView;
|
||||
import java.nio.file.attribute.PosixFileAttributes;
|
||||
import java.nio.file.attribute.PosixFilePermission;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@ -45,11 +44,7 @@ import java.util.zip.ZipOutputStream;
|
||||
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.cli.ExitCodes;
|
||||
import org.elasticsearch.common.cli.CliTool;
|
||||
import org.elasticsearch.common.cli.CliToolTestCase;
|
||||
import org.elasticsearch.common.cli.MockTerminal;
|
||||
import org.elasticsearch.common.cli.Terminal;
|
||||
import org.elasticsearch.cli.MockTerminal;
|
||||
import org.elasticsearch.cli.UserError;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.env.Environment;
|
||||
|
@ -22,15 +22,10 @@ package org.elasticsearch.plugins;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
import org.elasticsearch.cli.ExitCodes;
|
||||
import org.elasticsearch.common.cli.CliTool;
|
||||
import org.elasticsearch.common.cli.CliToolTestCase;
|
||||
import org.elasticsearch.common.cli.MockTerminal;
|
||||
import org.elasticsearch.common.cli.Terminal;
|
||||
import org.elasticsearch.cli.MockTerminal;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.env.Environment;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
|
@ -26,9 +26,7 @@ import java.nio.file.Path;
|
||||
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
import org.elasticsearch.cli.UserError;
|
||||
import org.elasticsearch.common.cli.CliToolTestCase;
|
||||
import org.elasticsearch.common.cli.MockTerminal;
|
||||
import org.elasticsearch.common.cli.Terminal;
|
||||
import org.elasticsearch.cli.MockTerminal;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.env.Environment;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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.cli;
|
||||
|
||||
import joptsimple.OptionSet;
|
||||
import org.elasticsearch.common.cli.Terminal;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.junit.Before;
|
||||
|
||||
/**
|
||||
* A base test case for cli tools.
|
||||
*/
|
||||
public abstract class CommandTestCase extends ESTestCase {
|
||||
|
||||
protected final MockTerminal terminal = new MockTerminal();
|
||||
|
||||
@Before
|
||||
public void resetTerminal() {
|
||||
terminal.reset();
|
||||
terminal.setVerbosity(Terminal.Verbosity.NORMAL);
|
||||
}
|
||||
|
||||
protected abstract Command newCommand();
|
||||
|
||||
public String execute(String... args) throws Exception {
|
||||
Command command = newCommand();
|
||||
OptionSet options = command.parser.parse(args);
|
||||
command.execute(terminal, options);
|
||||
return terminal.getOutput();
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.common.cli;
|
||||
package org.elasticsearch.cli;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
@ -27,6 +27,8 @@ import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
|
||||
import org.elasticsearch.common.cli.Terminal;
|
||||
|
||||
/**
|
||||
* A terminal for tests which captures all output, and
|
||||
* can be plugged with fake input.
|
||||
@ -78,8 +80,10 @@ public class MockTerminal extends Terminal {
|
||||
return buffer.toString("UTF-8");
|
||||
}
|
||||
|
||||
/** Wipes the output. */
|
||||
public void resetOutput() {
|
||||
/** Wipes the input and output. */
|
||||
public void reset() {
|
||||
buffer.reset();
|
||||
textInput.clear();
|
||||
secretInput.clear();
|
||||
}
|
||||
}
|
@ -21,6 +21,7 @@ package org.elasticsearch.common.cli;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.elasticsearch.cli.MockTerminal;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.SuppressForbidden;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
|
Loading…
x
Reference in New Issue
Block a user