From b65dbbf19dc90f7470755ae52ba3ea36c439fa80 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov Date: Fri, 6 Jul 2012 18:55:44 +0600 Subject: [PATCH] SONAR-3626 CommandExecutor: should be possible to specify environment variables --- .../org/sonar/api/utils/command/Command.java | 21 +++++++ .../api/utils/command/CommandExecutor.java | 5 ++ .../utils/command/CommandExecutorTest.java | 58 ++++++++----------- sonar-plugin-api/src/test/scripts/echo.bat | 3 +- sonar-plugin-api/src/test/scripts/echo.sh | 3 +- 5 files changed, 55 insertions(+), 35 deletions(-) diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/command/Command.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/command/Command.java index 892325a12d3..461c82f11f3 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/command/Command.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/command/Command.java @@ -21,12 +21,14 @@ package org.sonar.api.utils.command; import com.google.common.base.Joiner; import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import org.apache.commons.lang.StringUtils; import java.io.File; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Map; /** * @since 2.7 @@ -36,6 +38,7 @@ public final class Command { private String executable; private List arguments = Lists.newArrayList(); private File directory; + private Map env = Maps.newHashMap(); private Command(String executable) { this.executable = executable; @@ -68,11 +71,29 @@ public final class Command { return directory; } + /** + * Sets working directory. + */ public Command setDirectory(File d) { this.directory = d; return this; } + /** + * @since 3.2 + */ + public Command setEnvironmentVariable(String name, String value) { + this.env.put(name, value); + return this; + } + + /** + * @since 3.2 + */ + public Map getEnvironmentVariables() { + return Collections.unmodifiableMap(env); + } + String[] toStrings() { List command = Lists.newArrayList(); command.add(executable); diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/command/CommandExecutor.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/command/CommandExecutor.java index 3ce60a6f315..05de3914947 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/command/CommandExecutor.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/command/CommandExecutor.java @@ -27,6 +27,7 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.util.Map; import java.util.concurrent.*; /** @@ -63,6 +64,10 @@ public final class CommandExecutor { if (command.getDirectory() != null) { builder.directory(command.getDirectory()); } + Map envVars = command.getEnvironmentVariables(); + if (!envVars.isEmpty()) { + builder.environment().putAll(envVars); + } process = builder.start(); outputGobbler = new StreamGobbler(process.getInputStream(), stdOut); diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/command/CommandExecutorTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/command/CommandExecutorTest.java index 6bcb1307e51..b06194bbbd8 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/utils/command/CommandExecutorTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/command/CommandExecutorTest.java @@ -31,11 +31,8 @@ import org.junit.rules.TestName; import java.io.File; import java.io.IOException; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.number.OrderingComparisons.greaterThanOrEqualTo; -import static org.junit.Assert.assertThat; +import static org.fest.assertions.Assertions.assertThat; import static org.junit.Assert.fail; -import static org.junit.matchers.JUnitMatchers.containsString; public class CommandExecutorTest { @@ -56,7 +53,7 @@ public class CommandExecutorTest { } @Test - public void shouldConsumeStdOutAndStdErr() throws Exception { + public void should_consume_StdOut_and_StdErr() throws Exception { final StringBuilder stdOutBuilder = new StringBuilder(); StreamConsumer stdOutConsumer = new StreamConsumer() { public void consumeLine(String line) { @@ -71,18 +68,18 @@ public class CommandExecutorTest { }; Command command = Command.create(getScript("output")).setDirectory(workDir); int exitCode = CommandExecutor.create().execute(command, stdOutConsumer, stdErrConsumer, 1000L); - assertThat(exitCode, is(0)); + assertThat(exitCode).isEqualTo(0); String stdOut = stdOutBuilder.toString(); String stdErr = stdErrBuilder.toString(); - assertThat(stdOut, containsString("stdOut: first line")); - assertThat(stdOut, containsString("stdOut: second line")); - assertThat(stdErr, containsString("stdErr: first line")); - assertThat(stdErr, containsString("stdErr: second line")); + assertThat(stdOut).contains("stdOut: first line"); + assertThat(stdOut).contains("stdOut: second line"); + assertThat(stdErr).contains("stdErr: first line"); + assertThat(stdErr).contains("stdErr: second line"); } @Test - public void stdOutConsumerCanThrowException() throws Exception { + public void stdOut_consumer_can_throw_exception() throws Exception { Command command = Command.create(getScript("output")).setDirectory(workDir); thrown.expect(CommandException.class); thrown.expectMessage("Error inside stdOut parser"); @@ -90,7 +87,7 @@ public class CommandExecutorTest { } @Test - public void stdErrConsumerCanThrowException() throws Exception { + public void stdErr_consumer_can_throw_exception() throws Exception { Command command = Command.create(getScript("output")).setDirectory(workDir); thrown.expect(CommandException.class); thrown.expectMessage("Error inside stdErr parser"); @@ -110,28 +107,23 @@ public class CommandExecutorTest { }; @Test - public void shouldEchoArguments() throws IOException { - String executable = getScript("echo"); - int exitCode = CommandExecutor.create().execute(Command.create(executable), 1000L); - assertThat(exitCode, is(0)); - - // the script generates a log in current directory - FileUtils.deleteQuietly(new File("echo.log")); - } - - @Test - public void shouldConfigureWorkingDirectory() throws IOException { - String executable = getScript("echo"); - - int exitCode = CommandExecutor.create().execute(Command.create(executable).setDirectory(workDir), 1000L); - assertThat(exitCode, is(0)); - - File log = new File(workDir, "echo.log"); - assertThat(FileUtils.readFileToString(log), containsString(workDir.getCanonicalPath())); + public void should_use_working_directory_to_store_argument_and_environment_variable() throws Exception { + Command command = Command.create(getScript("echo")) + .setDirectory(workDir) + .addArgument("1") + .setEnvironmentVariable("ENVVAR", "2"); + int exitCode = CommandExecutor.create().execute(command, 1000L); + assertThat(exitCode).isEqualTo(0); + File logFile = new File(workDir, "echo.log"); + assertThat(logFile).exists(); + String log = FileUtils.readFileToString(logFile); + assertThat(log).contains(workDir.getCanonicalPath()); + assertThat(log).contains("Parameter: 1"); + assertThat(log).contains("Environment variable: 2"); } @Test - public void shouldStopWithTimeout() throws IOException { + public void should_stop_after_timeout() throws IOException { String executable = getScript("forever"); long start = System.currentTimeMillis(); try { @@ -141,12 +133,12 @@ public class CommandExecutorTest { long duration = System.currentTimeMillis() - start; // should test >= 300 but it strangly fails during build on windows. // The timeout is raised after 297ms (??) - assertThat(e.getMessage(), duration, greaterThanOrEqualTo(290L)); + assertThat(duration).as(e.getMessage()).isGreaterThan(290L); } } @Test - public void shouldFailIfScriptNotFound() { + public void should_fail_if_script_not_found() { thrown.expect(CommandException.class); CommandExecutor.create().execute(Command.create("notfound").setDirectory(workDir), 1000L); } diff --git a/sonar-plugin-api/src/test/scripts/echo.bat b/sonar-plugin-api/src/test/scripts/echo.bat index 0d2e92c40b6..0f828174ca5 100755 --- a/sonar-plugin-api/src/test/scripts/echo.bat +++ b/sonar-plugin-api/src/test/scripts/echo.bat @@ -1,3 +1,4 @@ @ECHO OFF @ECHO %CD% > echo.log -@ECHO Parameter: %1 +@ECHO Parameter: %1 >> echo.log +@ECHO Environment variable: %ENVVAR >> echo.log diff --git a/sonar-plugin-api/src/test/scripts/echo.sh b/sonar-plugin-api/src/test/scripts/echo.sh index 487e35e0257..8931fd8e903 100755 --- a/sonar-plugin-api/src/test/scripts/echo.sh +++ b/sonar-plugin-api/src/test/scripts/echo.sh @@ -2,4 +2,5 @@ WORKING_DIR=`pwd` echo $WORKING_DIR > echo.log -echo "Parameter: $1" +echo "Parameter: $1" >> echo.log +echo "Environment variable: $ENVVAR" >> echo.log -- 2.39.5