summaryrefslogtreecommitdiffstats
path: root/sonar-plugin-api
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@gmail.com>2013-12-17 12:09:52 +0100
committerSimon Brandhof <simon.brandhof@gmail.com>2013-12-17 12:09:52 +0100
commit2f82a417928c69f1b3d34c49532eed07c90689e9 (patch)
treeb7fcc608f7d736e42ea20dd7a63691de188b6aaf /sonar-plugin-api
parent15840de6781ce67c5acc948f4b45a67d842f742d (diff)
downloadsonarqube-2f82a417928c69f1b3d34c49532eed07c90689e9.tar.gz
sonarqube-2f82a417928c69f1b3d34c49532eed07c90689e9.zip
New class System2 to increase testability of classes that call low-level system methods
Diffstat (limited to 'sonar-plugin-api')
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/System2.java102
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/utils/command/Command.java29
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/utils/System2Test.java72
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/utils/command/CommandExecutorTest.java3
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/utils/command/CommandTest.java43
5 files changed, 220 insertions, 29 deletions
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/System2.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/System2.java
new file mode 100644
index 00000000000..a87dedbdb33
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/System2.java
@@ -0,0 +1,102 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube 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 program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.utils;
+
+import org.apache.commons.lang.SystemUtils;
+
+import javax.annotation.CheckForNull;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * Proxy over {@link java.lang.System}. It aims to improve testability of classes
+ * that interact with low-level system methods, for example :
+ *
+ * <pre>
+ * public class MyClass {
+ * private final System2 system;
+ *
+ * public MyClass(System2 s) {
+ * this.system = s;
+ * }
+ *
+ * public long xxx() {
+ * return system.now();
+ * }
+ * }
+ *
+ * @Test
+ * public void should_return_xxx() {
+ * System2 system = mock(System2.class);
+ * long now = parse("2013-12-25");
+ * doReturn(now).when(system).now();
+ * assertThat(new MyClass(system).xxx()).isEqualTo(now);
+ * }
+ * </pre>
+ *
+ * @since 4.2
+ */
+public class System2 {
+
+ public static final System2 INSTANCE = new System2();
+
+ /**
+ * Shortcut for {@link System#currentTimeMillis()}
+ */
+ public long now() {
+ return System.currentTimeMillis();
+ }
+
+ /**
+ * Shortcut for {@link System#getProperties()}
+ */
+ public Properties properties() {
+ return System.getProperties();
+ }
+
+ /**
+ * Shortcut for {@link System#getProperty(String)}
+ */
+ @CheckForNull
+ public String property(String key) {
+ return System.getProperty(key);
+ }
+
+ /**
+ * Shortcut for {@link System#getenv()}
+ */
+ public Map<String, String> envVariables() {
+ return System.getenv();
+ }
+
+ /**
+ * Shortcut for {@link System#getenv(String)}
+ */
+ public String envVariable(String key) {
+ return System.getenv(key);
+ }
+
+ /**
+ * True if this is MS Windows.
+ */
+ public boolean isOsWindows() {
+ return SystemUtils.IS_OS_WINDOWS;
+ }
+}
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 c53563ce216..7a39f6a2a7b 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
@@ -26,7 +26,7 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.lang.StringUtils;
-import org.apache.commons.lang.SystemUtils;
+import org.sonar.api.utils.System2;
import java.io.File;
import java.util.Collections;
@@ -39,13 +39,25 @@ import java.util.Map;
public class Command {
private final String executable;
private final List<String> arguments = Lists.newArrayList();
- private final Map<String, String> env = Maps.newHashMap(System.getenv());
+ private final Map<String, String> env;
private File directory;
private boolean newShell = false;
+ private final System2 system;
- private Command(String executable) {
+ /**
+ * Create a command line without any arguments
+ *
+ * @param executable
+ */
+ public static Command create(String executable) {
+ return new Command(executable, System2.INSTANCE);
+ }
+
+ Command(String executable, System2 system) {
Preconditions.checkArgument(!StringUtils.isBlank(executable), "Command executable can not be blank");
this.executable = executable;
+ this.env = Maps.newHashMap(system.envVariables());
+ this.system = system;
}
public String getExecutable() {
@@ -130,7 +142,7 @@ public class Command {
List<String> toStrings() {
ImmutableList.Builder<String> command = ImmutableList.builder();
if (newShell) {
- if (SystemUtils.IS_OS_WINDOWS) {
+ if (system.isOsWindows()) {
command.add("cmd", "/C", "call");
} else {
command.add("sh");
@@ -149,13 +161,4 @@ public class Command {
public String toString() {
return toCommandLine();
}
-
- /**
- * Create a command line without any arguments
- *
- * @param executable
- */
- public static Command create(String executable) {
- return new Command(executable);
- }
}
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/System2Test.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/System2Test.java
new file mode 100644
index 00000000000..b81a065bacc
--- /dev/null
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/System2Test.java
@@ -0,0 +1,72 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube 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 program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.api.utils;
+
+import org.apache.commons.lang.SystemUtils;
+import org.junit.Test;
+
+import java.util.Map;
+import java.util.Properties;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.fest.assertions.Fail.fail;
+
+public class System2Test {
+ @Test
+ public void testNow() throws Exception {
+ long start = System.currentTimeMillis();
+ long now = System2.INSTANCE.now();
+ assertThat(now-start).isGreaterThanOrEqualTo(0).isLessThan(3);
+ }
+
+ @Test
+ public void testProperties() throws Exception {
+ Properties expected = System.getProperties();
+ assertThat(System2.INSTANCE.properties()).isNotNull().isEqualTo(expected);
+ }
+
+ @Test
+ public void testProperty() throws Exception {
+ String expected = System.getProperty("java.version");
+ assertThat(System2.INSTANCE.property("java.version")).isNotNull().isEqualTo(expected);
+ }
+
+ @Test
+ public void testEnvVariables() throws Exception {
+ Map<String,String> expected = System.getenv();
+ assertThat(System2.INSTANCE.envVariables()).isNotNull().isEqualTo(expected);
+ }
+
+ @Test
+ public void testEnvVariable() throws Exception {
+ // assume that there's at least one env variable
+ if (System.getenv().isEmpty()) {
+ fail("Test can't succeed because there are no env variables. How is it possible ?");
+ }
+ String key = System.getenv().keySet().iterator().next();
+ String expected = System.getenv(key);
+ assertThat(System2.INSTANCE.envVariable(key)).isNotNull().isEqualTo(expected);
+ }
+
+ @Test
+ public void testIsOsWindows() throws Exception {
+ assertThat(System2.INSTANCE.isOsWindows()).isEqualTo(SystemUtils.IS_OS_WINDOWS);
+ }
+}
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 2c79502b9f2..e898a966819 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
@@ -27,6 +27,7 @@ import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.junit.rules.TestName;
+import org.sonar.api.utils.System2;
import java.io.File;
import java.io.IOException;
@@ -145,7 +146,7 @@ public class CommandExecutorTest {
private static String getScript(String name) throws IOException {
String filename;
- if (SystemUtils.IS_OS_WINDOWS) {
+ if (System2.INSTANCE.isOsWindows()) {
filename = name + ".bat";
} else {
filename = name + ".sh";
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/command/CommandTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/command/CommandTest.java
index db99f370078..296b19859a1 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/utils/command/CommandTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/command/CommandTest.java
@@ -19,15 +19,18 @@
*/
package org.sonar.api.utils.command;
-import org.apache.commons.lang.SystemUtils;
+import com.google.common.collect.ImmutableMap;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
+import org.sonar.api.utils.System2;
import java.io.File;
import java.util.Arrays;
import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
public class CommandTest {
@@ -82,24 +85,34 @@ public class CommandTest {
@Test
public void override_env_variables() {
- Command command = Command.create("java");
- command.setEnvironmentVariable("JAVA_HOME", "/path/to/java");
- assertThat(command.getEnvironmentVariables().get("JAVA_HOME")).isEqualTo("/path/to/java");
+ System2 system = mock(System2.class);
+ when(system.envVariables()).thenReturn(ImmutableMap.of("JAVA_HOME", "/default/path/to/java"));
+
+ Command command = new Command("java", system);
+ command.setEnvironmentVariable("JAVA_HOME", "/new/path/to/java");
+ assertThat(command.getEnvironmentVariables().get("JAVA_HOME")).isEqualTo("/new/path/to/java");
}
@Test
- public void should_use_new_shell() {
- if (SystemUtils.IS_OS_WINDOWS) {
- Command command = Command.create("foo.bat");
- command.setNewShell(true);
- assertThat(command.toCommandLine()).isEqualTo("cmd /C call foo.bat");
+ public void should_use_cmd_for_new_shell_on_windows() {
+ System2 system = mock(System2.class);
+ when(system.isOsWindows()).thenReturn(true);
+ Command command = new Command("foo.bat", system);
+ command.setNewShell(true);
+ assertThat(command.toCommandLine()).isEqualTo("cmd /C call foo.bat");
assertThat(command.isNewShell()).isTrue();
- } else {
- Command command = Command.create("foo.sh");
- command.setNewShell(true);
- assertThat(command.toCommandLine()).isEqualTo("sh foo.sh");
- assertThat(command.isNewShell()).isTrue();
- }
+
+ }
+
+ @Test
+ public void should_use_sh_for_new_shell_on_unix() {
+ System2 system = mock(System2.class);
+ when(system.isOsWindows()).thenReturn(false);
+ Command command = new Command("foo.sh", system);
+
+ command.setNewShell(true);
+ assertThat(command.toCommandLine()).isEqualTo("sh foo.sh");
+ assertThat(command.isNewShell()).isTrue();
}
@Test