Mercurial > hg > release > thermostat-1.4
changeset 1756:a385e862f77f
Run original command if not previously configured and setup intercepted.
Reviewed-by: omajid
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2015-August/015439.html
PR2581
author | Severin Gehwolf <sgehwolf@redhat.com> |
---|---|
date | Thu, 03 Sep 2015 11:20:14 +0200 |
parents | 5abd45b55267 |
children | 47760bc2a861 |
files | launcher/src/main/java/com/redhat/thermostat/launcher/internal/LauncherImpl.java launcher/src/test/java/com/redhat/thermostat/launcher/internal/LauncherImplTest.java setup-command/command/src/main/java/com/redhat/thermostat/setup/command/SetupCommand.java setup-command/command/src/main/java/com/redhat/thermostat/setup/command/internal/SetupWindow.java setup-command/command/src/test/java/com/redhat/thermostat/setup/command/SetupCommandTest.java setup-command/distribution/thermostat-plugin.xml |
diffstat | 6 files changed, 217 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/launcher/src/main/java/com/redhat/thermostat/launcher/internal/LauncherImpl.java Wed Sep 02 15:27:53 2015 +0200 +++ b/launcher/src/main/java/com/redhat/thermostat/launcher/internal/LauncherImpl.java Thu Sep 03 11:20:14 2015 +0200 @@ -157,14 +157,11 @@ } else { // With web-always-on we need to make sure that the setup ran. if (isThermostatConfigured()) { + logger.log(Level.FINE, "Running command without setup interception."); runCommandFromArguments(args, listeners, inShell); } else { - if (Arrays.asList(args).contains("--skip-setup")) { - runCommandFromArguments(args, listeners, inShell); - } else { - String[] setupArgs = {"setup"}; - runCommandFromArguments(setupArgs, listeners, inShell); - } + logger.log(Level.FINE, "Running command through setup."); + runSetupThenInterceptedCommand(args); } } } catch (NoClassDefFoundError e) { @@ -188,11 +185,32 @@ } } } + + private void runSetupThenInterceptedCommand(String[] originalCmdArgs) { + String origCmdArgs = convertOriginalArgsToString(originalCmdArgs); + String[] setupArgs = { "setup", + "--origArgs", + origCmdArgs + }; + runCommandFromArguments(setupArgs, null, false); + } - // Log messages might go to a file. Be sure to print to stdout as well. - private void printAndLogLine(String msg) { - System.out.println(msg); - logger.log(Level.INFO, msg); + private String convertOriginalArgsToString(String[] origArgs) { + if (origArgs.length == 0) { + throw new AssertionError("Running setup with no argument?"); + } + final String separator = "|||"; + // single argument + if (origArgs.length == 1) { + return origArgs[0]; + } + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < origArgs.length - 1; i++) { + buffer.append(origArgs[i]); + buffer.append(separator); + } + buffer.append(origArgs[origArgs.length - 1]); + return buffer.toString(); } private boolean isThermostatConfigured() throws InvalidConfigurationException { @@ -247,7 +265,8 @@ runCommand(HELP_COMMAND_NAME, new String[] { "--", cmdName }, null, false); } - private void runCommandFromArguments(String[] args, Collection<ActionListener<ApplicationState>> listeners, boolean inShell) { + // package-private for testing + void runCommandFromArguments(String[] args, Collection<ActionListener<ApplicationState>> listeners, boolean inShell) { runCommand(args[0], Arrays.copyOfRange(args, 1, args.length), listeners, inShell); } @@ -420,5 +439,6 @@ } } } + }
--- a/launcher/src/test/java/com/redhat/thermostat/launcher/internal/LauncherImplTest.java Wed Sep 02 15:27:53 2015 +0200 +++ b/launcher/src/test/java/com/redhat/thermostat/launcher/internal/LauncherImplTest.java Thu Sep 03 11:20:14 2015 +0200 @@ -48,8 +48,11 @@ import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.EnumSet; +import java.util.List; +import java.util.Objects; import java.util.concurrent.ExecutorService; import java.util.logging.Handler; import java.util.logging.Level; @@ -58,6 +61,8 @@ import org.apache.commons.cli.Option; import org.apache.commons.cli.Options; +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; @@ -70,6 +75,7 @@ import com.redhat.thermostat.common.ActionNotifier; import com.redhat.thermostat.common.ApplicationService; import com.redhat.thermostat.common.ExitStatus; +import com.redhat.thermostat.common.Pair; import com.redhat.thermostat.common.Version; import com.redhat.thermostat.common.cli.AbstractStateNotifyingCommand; import com.redhat.thermostat.common.cli.Arguments; @@ -239,6 +245,7 @@ when(infos.getCommandInfo(name4)).thenReturn(info4); when(infos.getCommandInfo("basic")).thenReturn(basicInfo); when(infos.getCommandInfo("help")).thenReturn(helpCommandInfo); + when(infos.getCommandInfo("setup")).thenReturn(mock(CommandInfo.class)); Collection<CommandInfo> infoList = new ArrayList<CommandInfo>(); infoList.add(helpCommandInfo); @@ -682,6 +689,60 @@ runAndVerifyCommand(new String[] { cmdName }, expected, isInShell); } + @Test + public void verifyOriginalCmdArgsArePassedOnToSetup() { + String[] argsList = new String[] { "list-vms", "--dbUrl=foo" }; + List<Pair<String[], Boolean>> resultList = doOriginalCmdArgsArePassedOnToSetupTest(argsList); + assertEquals("Expected to run only setup", 1, resultList.size()); + Pair<String[], Boolean> actual = resultList.get(0); + assertFalse("Expected to run outside shell", actual.getSecond()); + String[] expectedList = new String[] { "setup", "--origArgs", "list-vms|||--dbUrl=foo" }; + assertArrayEquals(expectedList, actual.getFirst()); + } + + @Test + public void verifyOriginalCmdArgsArePassedOnToSetup2() { + String[] argsList = new String[] { "web-storage-service" }; + List<Pair<String[], Boolean>> resultList = doOriginalCmdArgsArePassedOnToSetupTest(argsList); + assertEquals("Expected to run only setup", 1, resultList.size()); + Pair<String[], Boolean> actual = resultList.get(0); + assertFalse("Expected to run outside shell", actual.getSecond()); + String[] expectedList = new String[] { "setup", "--origArgs", "web-storage-service" }; + assertArrayEquals(expectedList, actual.getFirst()); + } + + private List<Pair<String[], Boolean>> doOriginalCmdArgsArePassedOnToSetupTest(String[] args) { + CommonPaths setupPaths = mock(CommonPaths.class); + File mockFile = mock(File.class); + when(mockFile.exists()).thenReturn(false); + when(setupPaths.getUserSetupCompleteStampFile()).thenReturn(mockFile); + File fileWithAbsPath = mock(File.class); + when(setupPaths.getSystemThermostatHome()).thenReturn(fileWithAbsPath); + when(setupPaths.getUserThermostatHome()).thenReturn(fileWithAbsPath); + final List<Pair<String[], Boolean>> runList = new ArrayList<>(); + launcher = new LauncherImpl(bundleContext, ctxFactory, registry, infos, + new CommandSource(bundleContext), environment, + dbServiceFactory, version, + mock(ClientPreferences.class), + mock(Keyring.class), setupPaths, mock(LoggingInitializer.class)) { + @Override + void runCommandFromArguments(String[] args, Collection<ActionListener<ApplicationState>> listeners, boolean inShell) { + Pair<String[], Boolean> pair = new Pair<>(args, inShell); + runList.add(pair); + } + }; + + wrappedRun(launcher, args, false, null); + return runList; + } + + private void assertArrayEquals(String[] expected, String[] actual) { + assertTrue(expected.length == actual.length); + for (int i = 0; i < expected.length; i++) { + assertEquals(expected[i], actual[i]); + } + } + private static class TestLogHandler extends Handler { private boolean loggedThermostatHome; @@ -710,5 +771,6 @@ } } + }
--- a/setup-command/command/src/main/java/com/redhat/thermostat/setup/command/SetupCommand.java Wed Sep 02 15:27:53 2015 +0200 +++ b/setup-command/command/src/main/java/com/redhat/thermostat/setup/command/SetupCommand.java Thu Sep 03 11:20:14 2015 +0200 @@ -38,12 +38,16 @@ import java.awt.EventQueue; import java.lang.reflect.InvocationTargetException; +import java.util.logging.Level; +import java.util.logging.Logger; import com.redhat.thermostat.common.cli.AbstractCommand; +import com.redhat.thermostat.common.cli.Arguments; import com.redhat.thermostat.common.cli.CommandContext; import com.redhat.thermostat.common.cli.CommandException; import com.redhat.thermostat.common.cli.Console; import com.redhat.thermostat.common.cli.DependencyServices; +import com.redhat.thermostat.common.utils.LoggingUtils; import com.redhat.thermostat.internal.utils.laf.ThemeManager; import com.redhat.thermostat.launcher.Launcher; import com.redhat.thermostat.setup.command.internal.SetupWindow; @@ -53,15 +57,24 @@ public class SetupCommand extends AbstractCommand { + private static final String ORIG_CMD_ARGUMENT_NAME = "origArgs"; + private static final Logger logger = LoggingUtils.getLogger(SetupCommand.class); private final DependencyServices dependentServices = new DependencyServices(); private SetupWindow mainWindow; private CommonPaths paths; private Launcher launcher; private ThermostatSetup thermostatSetup; private Console console; + private String[] origArgsList; @Override public void run(CommandContext ctx) throws CommandException { + Arguments args = ctx.getArguments(); + if (args.hasArgument(ORIG_CMD_ARGUMENT_NAME)) { + String origArgs = args.getArgument(ORIG_CMD_ARGUMENT_NAME); + origArgsList = origArgs.split("\\|\\|\\|"); + } + this.console = ctx.getConsole(); try { @@ -76,6 +89,22 @@ } catch (InterruptedException | InvocationTargetException e) { throw new CommandException(new LocalizedString("SetupCommand failed to run"), e); } + runOriginalCommand(origArgsList); + } + + private void runOriginalCommand(String[] args) { + if (args == null) { + return; + } + if (args.length == 0) { + throw new AssertionError("Original command args were empty!"); + } + if (args[0].equals("setup")) { + // Do not run setup recursively + return; + } + logger.log(Level.FINE, "Running intercepted command '" + args[0] + "' after setup."); + launcher.run(args, false); } public void setPaths(CommonPaths paths) {
--- a/setup-command/command/src/main/java/com/redhat/thermostat/setup/command/internal/SetupWindow.java Wed Sep 02 15:27:53 2015 +0200 +++ b/setup-command/command/src/main/java/com/redhat/thermostat/setup/command/internal/SetupWindow.java Thu Sep 03 11:20:14 2015 +0200 @@ -281,6 +281,10 @@ } private void shutdown() { + // Explicitly dispose the window on shutdown since we might have + // intercepted another command and the window would otherwise + // stay open. + frame.dispose(); shutdown.countDown(); } }
--- a/setup-command/command/src/test/java/com/redhat/thermostat/setup/command/SetupCommandTest.java Wed Sep 02 15:27:53 2015 +0200 +++ b/setup-command/command/src/test/java/com/redhat/thermostat/setup/command/SetupCommandTest.java Thu Sep 03 11:20:14 2015 +0200 @@ -38,15 +38,23 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import static org.mockito.Matchers.argThat; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.io.ByteArrayOutputStream; import java.io.PrintStream; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.Objects; +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; import org.junit.Before; import org.junit.Test; @@ -158,6 +166,49 @@ } } + @Test + public void verifyOriginalCommandRunsAfterSetup() throws CommandException { + doTestOriginalCmdRunsAfterSetup("web-storage-service", new String[] { + "web-storage-service" + }); + } + + @Test + public void verifyOriginalCommandRunsAfterSetup2() throws CommandException { + doTestOriginalCmdRunsAfterSetup("list-vms|||--dbUrl=mongodb://127.0.0.1:25718", new String[] { + "list-vms", "--dbUrl=mongodb://127.0.0.1:25718" + }); + } + + @Test + public void verifySetupAsOrigCommandDoesNotRunAgain() throws CommandException { + cmd = createSetupCommand(); + setServices(); + + Arguments args = mock(Arguments.class); + CommandContext ctxt = mock(CommandContext.class); + when(ctxt.getArguments()).thenReturn(args); + when(args.hasArgument("origArgs")).thenReturn(true); + when(args.getArgument("origArgs")).thenReturn("setup"); + + cmd.run(ctxt); + verify(launcher, times(0)).run(argThat(new ArgsMatcher(new String[] { "setup" })), eq(false)); + } + + private void doTestOriginalCmdRunsAfterSetup(String origArgs, String[] argsList) throws CommandException { + cmd = createSetupCommand(); + setServices(); + + Arguments args = mock(Arguments.class); + CommandContext ctxt = mock(CommandContext.class); + when(ctxt.getArguments()).thenReturn(args); + when(args.hasArgument("origArgs")).thenReturn(true); + when(args.getArgument("origArgs")).thenReturn(origArgs); + + cmd.run(ctxt); + verify(launcher).run(argThat(new ArgsMatcher(argsList)), eq(false)); + } + private SetupCommand createSetupCommand() { return new SetupCommand() { @Override @@ -176,6 +227,37 @@ cmd.setPaths(paths); cmd.setLauncher(launcher); } + + private static class ArgsMatcher extends BaseMatcher<String[]> { + + private final String[] expected; + + private ArgsMatcher(String[] expected) { + this.expected = expected; + } + + @Override + public boolean matches(Object arg0) { + if (arg0 == null || arg0.getClass() != String[].class) { + return false; + } + String[] other = (String[])arg0; + if (other.length != expected.length) { + return false; + } + boolean matches = true; + for (int i = 0; i < expected.length; i++) { + matches = matches && Objects.equals(expected[i], other[i]); + } + return matches; + } + + @Override + public void describeTo(Description arg0) { + arg0.appendText(Arrays.asList(expected).toString()); + } + + } }
--- a/setup-command/distribution/thermostat-plugin.xml Wed Sep 02 15:27:53 2015 +0200 +++ b/setup-command/distribution/thermostat-plugin.xml Thu Sep 03 11:20:14 2015 +0200 @@ -44,6 +44,15 @@ <name>setup</name> <summary>setup thermostat for first run</summary> <description>setup an initial mongodb user and webapp settings. Optionally create a client admin and agent user.</description> + <options> + <option> + <long>origArgs</long> + <short>o</short> + <argument>originalArgs</argument> + <required>false</required> + <description>A string holding '|||'-separated values of original arguments if a command got intercepted with setup.</description> + </option> + </options> <environments> <environment>cli</environment> <environment>shell</environment>