/*
* JBoss, Home of Professional Open Source.
* Copyright 2016, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.as.test.integration.management.cli;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import org.jboss.as.cli.Util;
import org.jboss.as.test.shared.TestSuiteEnvironment;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.fail;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.wildfly.core.testrunner.WildflyTestRunner;
/**
*
* @author jdenise@redhat.com
*/
@RunWith(WildflyTestRunner.class)
public class CliConfigTestCase {
@Rule
public final TemporaryFolder temporaryUserHome = new TemporaryFolder();
@Test
public void testEchoCommand() throws Exception {
File f = createConfigFile(true);
CliProcessWrapper cli = new CliProcessWrapper()
.setCliConfig(f.getAbsolutePath())
.addCliArgument("--command=version");
final String result = cli.executeNonInteractive();
assertNotNull(result);
assertTrue(result, result.contains("[disconnected /] version"));
}
@Test
public void testNoEchoCommand() throws Exception {
File f = createConfigFile(false);
CliProcessWrapper cli = new CliProcessWrapper()
.setCliConfig(f.getAbsolutePath())
.addCliArgument("--command=version");
final String result = cli.executeNonInteractive();
assertNotNull(result);
assertFalse(result, result.contains("[disconnected /] version"));
}
@Test
public void testWorkFlowEchoCommand() throws Exception {
File f = createConfigFile(true);
File script = createScript();
CliProcessWrapper cli = new CliProcessWrapper()
.setCliConfig(f.getAbsolutePath())
.addCliArgument("--file=" + script.getAbsolutePath())
.addCliArgument("--controller=" +
TestSuiteEnvironment.getServerAddress() + ":" +
TestSuiteEnvironment.getServerPort())
.addCliArgument("--connect");
final String result = cli.executeNonInteractive();
assertNotNull(result);
assertTrue(result, result.contains(":read-attribute(name=foo)"));
assertTrue(result, result.contains("/system-property=catch:add(value=bar)"));
assertTrue(result, result.contains("/system-property=finally:add(value=bar)"));
assertTrue(result, result.contains("/system-property=finally2:add(value=bar)"));
assertTrue(result, result.contains("if (outcome == success) of /system-property=catch:read-attribute(name=value)"));
assertTrue(result, result.contains("set prop=Catch\\ block\\ was\\ executed"));
assertTrue(result, result.contains("/system-property=finally:write-attribute(name=value, value=if)"));
assertFalse(result, result.contains("/system-property=catch2:add(value=bar)"));
assertFalse(result, result.contains("set prop=Catch\\ block\\ wasn\\'t\\ executed"));
assertFalse(result, result.contains("/system-property=finally:write-attribute(name=value, value=else)"));
assertTrue(result, result.contains("/system-property=catch:remove()"));
assertTrue(result, result.contains("/system-property=finally:remove()"));
assertTrue(result, result.contains("/system-property=finally2:remove()"));
}
@Test
public void testConfigTimeoutCommand() throws Exception {
File f = createConfigFile(false, 1);
CliProcessWrapper cli = new CliProcessWrapper()
.setCliConfig(f.getAbsolutePath())
.addJavaOption("-Duser.home=" + temporaryUserHome.getRoot().toPath().toString())
.addCliArgument("--controller="
+ TestSuiteEnvironment.getServerAddress() + ":"
+ TestSuiteEnvironment.getServerPort())
.addCliArgument("--connect");
cli.executeInteractive();
cli.clearOutput();
testTimeout(cli, 1);
}
@Test
public void testOptionTimeoutCommand() throws Exception {
CliProcessWrapper cli = new CliProcessWrapper()
.addJavaOption("-Duser.home=" + temporaryUserHome.getRoot().toPath().toString())
.addCliArgument("--controller="
+ TestSuiteEnvironment.getServerAddress() + ":"
+ TestSuiteEnvironment.getServerPort())
.addCliArgument("--connect")
.addCliArgument("--command-timeout=77");
cli.executeInteractive();
cli.clearOutput();
testTimeout(cli, 77);
}
@Test
public void testOptionFile() throws Exception {
testFileOption("file");
testFileOption("properties");
}
private void testFileOption(String optionName) throws Exception {
File f = new File(temporaryUserHome.getRoot(), "a-script"
+ System.currentTimeMillis() + ".cli");
f.createNewFile();
f.deleteOnExit();
{
CliProcessWrapper cli = new CliProcessWrapper()
.addJavaOption("-Duser.home=" + temporaryUserHome.getRoot().toPath().toString())
.addCliArgument("--" + optionName + "=" + "~" + File.separator + f.getName());
try {
cli.executeNonInteractive();
assertFalse(cli.getOutput(), cli.getOutput().contains(f.getName()));
} finally {
cli.destroyProcess();
}
}
{
CliProcessWrapper cli = new CliProcessWrapper()
.addJavaOption("-Duser.home=" + temporaryUserHome.getRoot().toPath().toString())
.addCliArgument("--" + optionName + "=" + "~"
+ temporaryUserHome.getRoot().getName() + File.separator + f.getName());
try {
cli.executeNonInteractive();
assertFalse(cli.getOutput(), cli.getOutput().contains(f.getName()));
} finally {
cli.destroyProcess();
}
}
{
String invalidPath = "~" + System.currentTimeMillis() + "@testOptionFile" + File.separator + f.getName();
CliProcessWrapper cli = new CliProcessWrapper()
.addJavaOption("-Duser.home=" + temporaryUserHome.getRoot().toPath().toString())
.addCliArgument("--" + optionName + "=" + invalidPath);
try {
cli.executeNonInteractive();
assertTrue(cli.getOutput(), cli.getOutput().contains(f.getName()));
} finally {
cli.destroyProcess();
}
}
}
@Test
public void testNegativeConfigTimeoutCommand() throws Exception {
File f = createConfigFile(false, -1);
CliProcessWrapper cli = new CliProcessWrapper()
.setCliConfig(f.getAbsolutePath())
.addCliArgument("--controller="
+ TestSuiteEnvironment.getServerAddress() + ":"
+ TestSuiteEnvironment.getServerPort())
.addCliArgument("--connect");
String output = cli.executeNonInteractive();
assertTrue(output, output.contains("The command-timeout must be a valid positive integer"));
}
@Test
public void testNegativeOptionTimeoutCommand() throws Exception {
CliProcessWrapper cli = new CliProcessWrapper()
.addCliArgument("--controller="
+ TestSuiteEnvironment.getServerAddress() + ":"
+ TestSuiteEnvironment.getServerPort())
.addCliArgument("--connect")
.addCliArgument("--command-timeout=-1");
String output = cli.executeNonInteractive();
assertTrue(output, output.contains("The command-timeout must be a valid positive integer"));
}
@Test
public void testNonInteractiveCommandTimeout() throws Exception {
File f = createConfigFile(true, 1);
File script = createScript2();
CliProcessWrapper cli = new CliProcessWrapper()
.setCliConfig(f.getAbsolutePath())
.addCliArgument("--file=" + script.getAbsolutePath())
.addCliArgument("--controller="
+ TestSuiteEnvironment.getServerAddress() + ":"
+ TestSuiteEnvironment.getServerPort())
.addCliArgument("--connect");
final String result = cli.executeNonInteractive();
assertNotNull(result);
assertTrue(result, result.contains("Timeout exception for run-batch"));
}
@Test
public void testValidateOperation() throws Exception {
File f = createConfigFile(false, 0, true);
CliProcessWrapper cli = new CliProcessWrapper()
.setCliConfig(f.getAbsolutePath())
.addJavaOption("-Duser.home=" + temporaryUserHome.getRoot().toPath().toString())
.addCliArgument("--controller="
+ TestSuiteEnvironment.getServerAddress() + ":"
+ TestSuiteEnvironment.getServerPort())
.addCliArgument("--connect");
cli.executeInteractive();
cli.clearOutput();
cli.pushLineAndWaitForResults(":read-children-names(aaaaa,child-type=subsystem");
String str = cli.getOutput();
assertTrue(str, str.contains("'aaaaa' is not found among the supported properties:"));
}
@Test
public void testNotValidateOperation() throws Exception {
File f = createConfigFile(false, 0, false);
CliProcessWrapper cli = new CliProcessWrapper()
.setCliConfig(f.getAbsolutePath())
.addJavaOption("-Duser.home=" + temporaryUserHome.getRoot().toPath().toString())
.addCliArgument("--controller="
+ TestSuiteEnvironment.getServerAddress() + ":"
+ TestSuiteEnvironment.getServerPort())
.addCliArgument("--connect");
cli.executeInteractive();
cli.clearOutput();
cli.pushLineAndWaitForResults(":read-children-names(aaaaa,child-type=subsystem");
String str = cli.getOutput();
assertTrue(str, str.contains("\"outcome\" => \"success\","));
}
private void testTimeout(CliProcessWrapper cli, int config) throws Exception {
cli.pushLineAndWaitForResults("command-timeout get");
String str = cli.getOutput();
assertEquals("Original value " + str, getValue(str), "" + config);
cli.clearOutput();
cli.pushLineAndWaitForResults("command-timeout set 99");
cli.clearOutput();
cli.pushLineAndWaitForResults("command-timeout get");
assertEquals(getValue(cli.getOutput()), "" + 99);
cli.clearOutput();
cli.pushLineAndWaitForResults("command-timeout reset config");
cli.clearOutput();
cli.pushLineAndWaitForResults("command-timeout get");
assertEquals(getValue(cli.getOutput()), "" + config);
}
private static String getValue(String line) {
int i = line.indexOf("\n");
if (i > 0) {
line = line.substring(i + 1);
i = line.indexOf("\n");
if (i > 0) {
// On Windows, \r\n, don't keep it in the returned value.
line = line.substring(0, (Util.isWindows() ? i - 1 : i));
}
}
return line;
}
private static File createScript() {
File f = new File(TestSuiteEnvironment.getTmpDir(), "test-script" +
System.currentTimeMillis() + ".cli");
f.deleteOnExit();
try (Writer stream = Files.newBufferedWriter(f.toPath(), StandardCharsets.UTF_8)) {
stream.write("try\n");
stream.write(" :read-attribute(name=foo)\n");
stream.write("catch\n");
stream.write(" /system-property=catch:add(value=bar)\n");
stream.write("finally\n");
stream.write(" /system-property=finally:add(value=bar)\n");
stream.write("end-try\n");
stream.write("try\n");
stream.write(" /system-property=catch:read-attribute(name=value)\n");
stream.write("catch\n");
stream.write(" /system-property=catch2:add(value=bar)\n");
stream.write("finally\n");
stream.write(" /system-property=finally2:add(value=bar)\n");
stream.write(" end-try\n");
stream.write("/system-property=*:read-resource\n");
stream.write("if (outcome == success) of /system-property=catch:read-attribute(name=value)\n");
stream.write(" set prop=Catch\\ block\\ was\\ executed\n");
stream.write(" /system-property=finally:write-attribute(name=value, value=if)\n");
stream.write("else\n");
stream.write(" set prop=Catch\\ block\\ wasn\\'t\\ executed\n");
stream.write(" /system-property=finally:write-attribute(name=value, value=else)\n");
stream.write("end-if\n");
stream.write("/system-property=catch:remove()\n");
stream.write("/system-property=finally:remove()\n");
stream.write("/system-property=finally2:remove()\n");
} catch (IOException ex) {
fail("Failure creating script file " + ex);
}
return f;
}
private static File createScript2() {
File f = new File(TestSuiteEnvironment.getTmpDir(), "test-script"
+ System.currentTimeMillis() + ".cli");
f.deleteOnExit();
try (Writer stream = Files.newBufferedWriter(f.toPath(), StandardCharsets.UTF_8)) {
// This one should timeout in 1 sec...
stream.write("batch\n");
for (int i = 0; i < 300; i++) {
stream.write(":read-resource(recursive)\n");
}
stream.write("run-batch\n");
} catch (IOException ex) {
fail("Failure creating script file " + ex);
}
return f;
}
private static File createConfigFile(Boolean enable) {
return createConfigFile(enable, 0);
}
private static File createConfigFile(Boolean enable, int timeout) {
return createConfigFile(enable, timeout, true);
}
private static File createConfigFile(Boolean enable, int timeout, Boolean validate) {
File f = new File(TestSuiteEnvironment.getTmpDir(), "test-jboss-cli" +
System.currentTimeMillis() + ".xml");
f.deleteOnExit();
String namespace = "urn:jboss:cli:3.1";
XMLOutputFactory output = XMLOutputFactory.newInstance();
try (Writer stream = Files.newBufferedWriter(f.toPath(), StandardCharsets.UTF_8)) {
XMLStreamWriter writer = output.createXMLStreamWriter(stream);
writer.writeStartDocument();
writer.writeStartElement("jboss-cli");
writer.writeDefaultNamespace(namespace);
writer.writeStartElement("echo-command");
writer.writeCharacters(enable.toString());
writer.writeEndElement(); //echo-command
if (timeout != 0) {
writer.writeStartElement("command-timeout");
writer.writeCharacters("" + timeout);
writer.writeEndElement(); //command-timeout
}
writer.writeStartElement("validate-operation-requests");
writer.writeCharacters(validate.toString());
writer.writeEndElement(); //validate-operation-requests
writer.writeEndElement(); //jboss-cli
writer.writeEndDocument();
writer.flush();
writer.close();
} catch (XMLStreamException | IOException ex) {
fail("Failure creating config file " + ex);
}
return f;
}
}