SOLR-9610: New AssertTool in SolrCLI for easier cross platform assertions from command line

(cherry picked from commit 6512d0c)
This commit is contained in:
Jan Høydahl 2016-10-12 09:16:41 +02:00
parent 0375122c8e
commit df41706295
4 changed files with 233 additions and 2 deletions

View File

@ -232,6 +232,8 @@ Other Changes
* SOLR-8969: SQLHandler causes NPE in non-cloud mode (Markus Jelsma, Kevin Risden)
* SOLR-9610: New AssertTool in SolrCLI for easier cross platform assertions from command line (janhoy)
================== 6.2.1 ==================
Bug Fixes

View File

@ -636,6 +636,12 @@ if [ "$SCRIPT_CMD" == "status" ]; then
exit
fi
# assert tool
if [ "$SCRIPT_CMD" == "assert" ]; then
run_tool assert $*
exit $?
fi
# run a healthcheck and exit if requested
if [ "$SCRIPT_CMD" == "healthcheck" ]; then
@ -1042,7 +1048,7 @@ if [[ "$SCRIPT_CMD" == "zk" ]]; then
fi
# verify the command given is supported
if [ "$SCRIPT_CMD" != "stop" ] && [ "$SCRIPT_CMD" != "start" ] && [ "$SCRIPT_CMD" != "restart" ] && [ "$SCRIPT_CMD" != "status" ]; then
if [ "$SCRIPT_CMD" != "stop" ] && [ "$SCRIPT_CMD" != "start" ] && [ "$SCRIPT_CMD" != "restart" ] && [ "$SCRIPT_CMD" != "status" ] && [ "$SCRIPT_CMD" != "assert" ]; then
print_usage "" "$SCRIPT_CMD is not a valid command!"
exit 1
fi

View File

@ -103,6 +103,7 @@ IF "%1"=="status" goto get_info
IF "%1"=="version" goto get_version
IF "%1"=="-v" goto get_version
IF "%1"=="-version" goto get_version
IF "%1"=="assert" goto run_assert
REM Only allow the command to be the first argument, assume start if not supplied
IF "%1"=="start" goto set_script_cmd
@ -1076,6 +1077,15 @@ IF NOT DEFINED HEALTHCHECK_ZK_HOST set "HEALTHCHECK_ZK_HOST=localhost:9983"
org.apache.solr.util.SolrCLI healthcheck -collection !HEALTHCHECK_COLLECTION! -zkHost !HEALTHCHECK_ZK_HOST!
goto done
:run_assert
"%JAVA%" %SOLR_SSL_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" -Dlog4j.configuration="file:%DEFAULT_SERVER_DIR%\scripts\cloud-scripts\log4j.properties" ^
-classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^
org.apache.solr.util.SolrCLI %*
if errorlevel 1 (
exit /b 1
)
goto done
:get_version
"%JAVA%" %SOLR_SSL_OPTS% %SOLR_ZK_CREDS_AND_ACLS% -Dsolr.install.dir="%SOLR_TIP%" -Dlog4j.configuration="file:%DEFAULT_SERVER_DIR%\scripts\cloud-scripts\log4j.properties" ^
-classpath "%DEFAULT_SERVER_DIR%\solr-webapp\webapp\WEB-INF\lib\*;%DEFAULT_SERVER_DIR%\lib\ext\*" ^

View File

@ -30,6 +30,7 @@ import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.FileOwnerAttributeView;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@ -159,7 +160,7 @@ public class SolrCLI {
return toolExitStatus;
}
private void setBasicAuth(CommandLine cli) throws Exception {
protected void setBasicAuth(CommandLine cli) throws Exception {
String basicauth = System.getProperty("basicauth", null);
if (basicauth != null) {
List<String> ss = StrUtils.splitSmart(basicauth, ':');
@ -367,6 +368,8 @@ public class SolrCLI {
return new ZkCpTool();
else if ("ls".equals(toolType))
return new ZkLsTool();
else if ("assert".equals(toolType))
return new AssertTool();
// If you add a built-in tool to this class, add it here to avoid
// classpath scanning
@ -3129,4 +3132,214 @@ public class SolrCLI {
}
} // end RunExampleTool class
/**
* Asserts various conditions and exists with error code if fails, else continues with no output
*/
public static class AssertTool extends ToolBase {
private static String message = null;
private static boolean useExitCode = false;
public AssertTool() { this(System.out); }
public AssertTool(PrintStream stdout) { super(stdout); }
public String getName() {
return "assert";
}
@SuppressWarnings("static-access")
public Option[] getOptions() {
return new Option[] {
OptionBuilder
.withDescription("Asserts that we are NOT the root user")
.withLongOpt("not-root")
.create("R"),
OptionBuilder
.withDescription("Asserts that we are the root user")
.withLongOpt("root")
.create("r"),
OptionBuilder
.withDescription("Asserts that Solr is NOT started on a certain URL")
.withLongOpt("not-started")
.hasArg(true)
.withArgName("url")
.create("S"),
OptionBuilder
.withDescription("Asserts that Solr is started on a certain URL")
.withLongOpt("started")
.hasArg(true)
.withArgName("url")
.create("s"),
OptionBuilder
.withDescription("Asserts that we run as same user that owns <directory>")
.withLongOpt("same-user")
.hasArg(true)
.withArgName("directory")
.create("u"),
OptionBuilder
.withDescription("Asserts that directory <directory> exists")
.withLongOpt("exists")
.hasArg(true)
.withArgName("directory")
.create("x"),
OptionBuilder
.withDescription("Asserts that directory <directory> does NOT exist")
.withLongOpt("not-exists")
.hasArg(true)
.withArgName("directory")
.create("X"),
OptionBuilder
.withDescription("Exception message to be used in place of the default error message")
.withLongOpt("message")
.hasArg(true)
.withArgName("message")
.create("m"),
OptionBuilder
.withDescription("Return an exit code instead of printing error message on assert fail.")
.withLongOpt("exitcode")
.create("e")
};
}
public int runTool(CommandLine cli) throws Exception {
verbose = cli.hasOption("verbose");
int toolExitStatus = 0;
try {
setBasicAuth(cli);
toolExitStatus = runAssert(cli);
} catch (Exception exc) {
// since this is a CLI, spare the user the stacktrace
String excMsg = exc.getMessage();
if (excMsg != null) {
System.err.println("\nERROR: " + excMsg + "\n");
toolExitStatus = 1;
} else {
throw exc;
}
}
return toolExitStatus;
}
@Override
protected void runImpl(CommandLine cli) throws Exception {
runAssert(cli);
}
// Custom run method which may return exit code
protected int runAssert(CommandLine cli) throws Exception {
if (cli.getOptions().length == 0 || cli.getArgs().length > 0 || cli.hasOption("h")) {
new HelpFormatter().printHelp("bin/solr assert [-m <message>] [-e] [-rR] [-s <url>] [-S <url>] [-u <dir>] [-x <dir>] [-X <dir>]", getToolOptions(this));
return 1;
}
if (cli.hasOption("m")) {
message = cli.getOptionValue("m");
}
if (cli.hasOption("e")) {
useExitCode = true;
}
if (cli.hasOption("r")) {
if (assertRootUser() > 0) return 1;
}
if (cli.hasOption("R")) {
if (assertNotRootUser() > 0) return 1;
}
if (cli.hasOption("x")) {
if (assertFileExists(cli.getOptionValue("x")) > 0) return 1;
}
if (cli.hasOption("X")) {
if (assertFileNotExists(cli.getOptionValue("X")) > 0) return 1;
}
if (cli.hasOption("u")) {
if (sameUser(cli.getOptionValue("u")) > 0) return 1;
}
if (cli.hasOption("s")) {
if (assertSolrRunning(cli.getOptionValue("s")) > 0) return 1;
}
if (cli.hasOption("s")) {
if (assertSolrNotRunning(cli.getOptionValue("S")) > 0) return 1;
}
return 0;
}
public static int assertSolrRunning(String url) throws Exception {
StatusTool status = new StatusTool();
try {
status.waitToSeeSolrUp(url, 5);
} catch (Exception e) {
return exitOrException("Solr is not running on url " + url);
}
return 0;
}
public static int assertSolrNotRunning(String url) throws Exception {
StatusTool status = new StatusTool();
try {
status.waitToSeeSolrUp(url, 5);
return exitOrException("Solr is running on url " + url);
} catch (Exception e) { return 0; }
}
public static int sameUser(String directory) throws Exception {
if (Files.exists(Paths.get(directory))) {
String userForDir = userForDir(Paths.get(directory));
if (!currentUser().equals(userForDir)) {
return exitOrException("Must run as user " + userForDir + ". We are " + currentUser());
}
} else {
return exitOrException("Directory " + directory + " does not exist.");
}
return 0;
}
public static int assertFileExists(String directory) throws Exception {
if (! Files.exists(Paths.get(directory))) {
return exitOrException("Directory " + directory + " does not exist.");
}
return 0;
}
public static int assertFileNotExists(String directory) throws Exception {
if (Files.exists(Paths.get(directory))) {
return exitOrException("Directory " + directory + " should not exist.");
}
return 0;
}
public static int assertRootUser() throws Exception {
if (!currentUser().equals("root")) {
return exitOrException("Must run as root user");
}
return 0;
}
public static int assertNotRootUser() throws Exception {
if (currentUser().equals("root")) {
return exitOrException("Not allowed to run as root user");
}
return 0;
}
public static String currentUser() {
return System.getProperty("user.name");
}
public static String userForDir(Path pathToDir) {
try {
FileOwnerAttributeView ownerAttributeView = Files.getFileAttributeView(pathToDir, FileOwnerAttributeView.class);
return ownerAttributeView.getOwner().getName();
} catch (IOException e) {
return "N/A";
}
}
private static int exitOrException(String msg) throws Exception {
if (useExitCode) {
return 1;
} else {
throw new Exception(message != null ? message : msg);
}
}
} // end AssertTool class
}