aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDuarte Meneses <duarte.meneses@sonarsource.com>2015-10-09 10:28:47 +0200
committerDuarte Meneses <duarte.meneses@sonarsource.com>2015-10-09 12:58:42 +0200
commitfae90f2a020e9dd9cff5d8faffbdc17185c70f92 (patch)
tree745cb7339cb93de827a84eb2726fd6fb66fe3ecf
parent96f4a0a1a70cd4c73f5a997af1b7db715d95a2b5 (diff)
downloadsonar-scanner-cli-fae90f2a020e9dd9cff5d8faffbdc17185c70f92.tar.gz
sonar-scanner-cli-fae90f2a020e9dd9cff5d8faffbdc17185c70f92.zip
Improve decoupling and coverage
-rw-r--r--sonar-runner-api/src/test/java/org/sonar/runner/impl/IsolatedClassloaderTest.java68
-rw-r--r--sonar-runner-api/src/test/java/org/sonar/runner/impl/SimulatedLauncherTest.java25
-rw-r--r--sonar-runner-batch-interface/src/main/java/org/sonar/runner/batch/package-info.java20
-rw-r--r--sonar-runner-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java10
-rw-r--r--sonar-runner-batch/src/main/java/org/sonar/runner/batch/BatchFactory.java30
-rw-r--r--sonar-runner-batch/src/main/java/org/sonar/runner/batch/BatchIsolatedLauncher.java33
-rw-r--r--sonar-runner-batch/src/main/java/org/sonar/runner/batch/DefaultBatchFactory.java49
-rw-r--r--sonar-runner-batch/src/main/java/org/sonar/runner/batch/package-info.java20
-rw-r--r--sonar-runner-batch/src/test/java/org/sonar/runner/batch/BatchIsolatedLauncherTest.java107
-rw-r--r--sonar-runner-batch/src/test/java/org/sonar/runner/batch/DefaultBatchFactoryTest.java (renamed from sonar-runner-batch/src/test/java/org/sonar/runner/batch/IsolatedLauncherTest.java)8
10 files changed, 334 insertions, 36 deletions
diff --git a/sonar-runner-api/src/test/java/org/sonar/runner/impl/IsolatedClassloaderTest.java b/sonar-runner-api/src/test/java/org/sonar/runner/impl/IsolatedClassloaderTest.java
index b0a9276..3c7b2b8 100644
--- a/sonar-runner-api/src/test/java/org/sonar/runner/impl/IsolatedClassloaderTest.java
+++ b/sonar-runner-api/src/test/java/org/sonar/runner/impl/IsolatedClassloaderTest.java
@@ -19,9 +19,18 @@
*/
package org.sonar.runner.impl;
+import org.junit.Before;
+
+import java.io.File;
import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Enumeration;
import java.util.HashSet;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.mock;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@@ -31,16 +40,71 @@ public class IsolatedClassloaderTest {
@Rule
public ExpectedException thrown = ExpectedException.none();
+ private IsolatedClassloader classLoader;
+
+ @Before
+ public void setUp() {
+ ClassLoader parent = getClass().getClassLoader();
+ classLoader = new IsolatedClassloader(parent, new ClassloadRules(new HashSet<String>(), new HashSet<String>()));
+ }
+
@Test
public void should_use_isolated_system_classloader_when_parent_is_excluded() throws ClassNotFoundException, IOException {
thrown.expect(ClassNotFoundException.class);
thrown.expectMessage("org.junit.Test");
- ClassLoader parent = getClass().getClassLoader();
- IsolatedClassloader classLoader = new IsolatedClassloader(parent, new ClassloadRules(new HashSet<String>(), new HashSet<String>()));
// JUnit is available in the parent classloader (classpath used to execute this test) but not in the core JVM
assertThat(classLoader.loadClass("java.lang.String", false)).isNotNull();
classLoader.loadClass("org.junit.Test", false);
classLoader.close();
}
+
+ @Test
+ public void should_use_parent_to_load() throws ClassNotFoundException, IOException {
+ ClassloadRules rules = mock(ClassloadRules.class);
+ when(rules.canLoad("org.junit.Test")).thenReturn(true);
+ classLoader = new IsolatedClassloader(getClass().getClassLoader(), rules);
+ assertThat(classLoader.loadClass("org.junit.Test", false)).isNotNull();
+ }
+
+ @Test
+ public void add_jars() throws MalformedURLException {
+ File f = new File("dummy");
+ File[] files = {f};
+ classLoader.addFiles(Arrays.asList(files));
+
+ assertThat(classLoader.getURLs()).contains(f.toURI().toURL());
+ }
+
+ @Test
+ public void error_add_jars() {
+ File f = mock(File.class);
+ when(f.toURI()).thenThrow(MalformedURLException.class);
+ File[] files = {f};
+
+ thrown.expect(IllegalStateException.class);
+ thrown.expectMessage("Fail to create classloader");
+
+ classLoader.addFiles(Arrays.asList(files));
+ }
+
+ @Test
+ public void dont_get_resource_from_parent() {
+ URL resource2 = classLoader.getParent().getResource("fake.jar");
+ assertThat(resource2).isNotNull();
+
+ // should not find resource through parent classloader
+ URL resource = classLoader.getResource("fake.jar");
+ assertThat(resource).isNull();
+ }
+
+ @Test
+ public void dont_get_resources_from_parent() throws IOException {
+ Enumeration<URL> resource2 = classLoader.getParent().getResources("fake.jar");
+ assertThat(resource2.hasMoreElements()).isTrue();
+
+ // should not find resource through parent classloader
+ Enumeration<URL> resource = classLoader.getResources("fake.jar");
+ assertThat(resource.hasMoreElements()).isFalse();
+ }
}
diff --git a/sonar-runner-api/src/test/java/org/sonar/runner/impl/SimulatedLauncherTest.java b/sonar-runner-api/src/test/java/org/sonar/runner/impl/SimulatedLauncherTest.java
index ae4101b..37f1e9f 100644
--- a/sonar-runner-api/src/test/java/org/sonar/runner/impl/SimulatedLauncherTest.java
+++ b/sonar-runner-api/src/test/java/org/sonar/runner/impl/SimulatedLauncherTest.java
@@ -19,6 +19,7 @@
*/
package org.sonar.runner.impl;
+import org.sonar.runner.batch.IssueListener;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -28,8 +29,13 @@ import org.sonar.runner.cache.Logger;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
+import java.io.OutputStream;
import java.util.Properties;
+import static org.mockito.Mockito.doThrow;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
@@ -61,11 +67,30 @@ public class SimulatedLauncherTest {
assertDump(global, analysis);
}
+ @Test
+ public void testDump_with_issue_listener() throws IOException {
+ Properties global = new Properties();
+ global.putAll(createProperties(true));
+ Properties analysis = new Properties();
+ analysis.putAll(createProperties(false));
+
+ launcher.start(global, null, false);
+ launcher.execute(analysis, mock(IssueListener.class));
+ assertDump(global, analysis);
+ }
+
@Test(expected = IllegalStateException.class)
public void error_if_no_dump_file() {
launcher.execute(new Properties());
}
+ @Test(expected = IllegalStateException.class)
+ public void error_dump() throws IOException {
+ Properties p = mock(Properties.class);
+ doThrow(IOException.class).when(p).store(any(OutputStream.class), anyString());
+ launcher.execute(p);
+ }
+
@Test
public void no_ops() {
launcher.syncProject(null);
diff --git a/sonar-runner-batch-interface/src/main/java/org/sonar/runner/batch/package-info.java b/sonar-runner-batch-interface/src/main/java/org/sonar/runner/batch/package-info.java
new file mode 100644
index 0000000..97bc469
--- /dev/null
+++ b/sonar-runner-batch-interface/src/main/java/org/sonar/runner/batch/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * SonarQube Runner - Batch Interface
+ * Copyright (C) 2011 SonarSource
+ * sonarqube@googlegroups.com
+ *
+ * This program 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.
+ *
+ * This program 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 02
+ */
+package org.sonar.runner.batch;
diff --git a/sonar-runner-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java b/sonar-runner-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java
index 60f1465..e306ea2 100644
--- a/sonar-runner-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java
+++ b/sonar-runner-batch/src/main/java/org/sonar/batch/bootstrapper/Batch.java
@@ -28,7 +28,7 @@ import org.picocontainer.annotations.Nullable;
*
* @since 2.14
*/
-public final class Batch {
+public class Batch {
private Batch(Builder builder) {
}
@@ -52,7 +52,7 @@ public final class Batch {
return start(false);
}
- public synchronized Batch start(boolean forceSync) {
+ public synchronized Batch start(boolean preferCache) {
return this;
}
@@ -83,12 +83,6 @@ public final class Batch {
public synchronized void stop() {
}
- private void doStop(boolean swallowException) {
- }
-
- private void configureLogging() {
- }
-
public static Builder builder() {
return new Builder();
}
diff --git a/sonar-runner-batch/src/main/java/org/sonar/runner/batch/BatchFactory.java b/sonar-runner-batch/src/main/java/org/sonar/runner/batch/BatchFactory.java
new file mode 100644
index 0000000..e899ba0
--- /dev/null
+++ b/sonar-runner-batch/src/main/java/org/sonar/runner/batch/BatchFactory.java
@@ -0,0 +1,30 @@
+/*
+ * SonarQube Runner - Batch
+ * Copyright (C) 2011 SonarSource
+ * sonarqube@googlegroups.com
+ *
+ * This program 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.
+ *
+ * This program 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 02
+ */
+package org.sonar.runner.batch;
+
+import org.picocontainer.annotations.Nullable;
+import org.sonar.batch.bootstrapper.Batch;
+
+import java.util.List;
+import java.util.Properties;
+
+interface BatchFactory {
+ Batch createBatch(Properties properties, @Nullable final org.sonar.runner.batch.LogOutput logOutput, @Nullable List<Object> extensions);
+}
diff --git a/sonar-runner-batch/src/main/java/org/sonar/runner/batch/BatchIsolatedLauncher.java b/sonar-runner-batch/src/main/java/org/sonar/runner/batch/BatchIsolatedLauncher.java
index b7a49f3..1ac82f1 100644
--- a/sonar-runner-batch/src/main/java/org/sonar/runner/batch/BatchIsolatedLauncher.java
+++ b/sonar-runner-batch/src/main/java/org/sonar/runner/batch/BatchIsolatedLauncher.java
@@ -28,9 +28,7 @@ import java.util.List;
import java.util.Map;
import java.util.Properties;
-import org.picocontainer.annotations.Nullable;
import org.sonar.batch.bootstrapper.Batch;
-import org.sonar.batch.bootstrapper.EnvironmentInformation;
/**
* This class is executed within the classloader provided by the server. It contains the installed plugins and
@@ -38,10 +36,19 @@ import org.sonar.batch.bootstrapper.EnvironmentInformation;
*/
public class BatchIsolatedLauncher implements IsolatedLauncher {
private Batch batch = null;
+ private BatchFactory factory = null;
+
+ public BatchIsolatedLauncher() {
+ this.factory = new DefaultBatchFactory();
+ }
+
+ public BatchIsolatedLauncher(BatchFactory factory) {
+ this.factory = factory;
+ }
@Override
public void start(Properties globalProperties, org.sonar.runner.batch.LogOutput logOutput, boolean preferCache) {
- batch = createBatch(globalProperties, logOutput, null);
+ batch = factory.createBatch(globalProperties, logOutput, null);
batch.start(preferCache);
}
@@ -66,30 +73,12 @@ public class BatchIsolatedLauncher implements IsolatedLauncher {
batch.syncProject(projectKey);
}
- Batch createBatch(Properties properties, @Nullable final org.sonar.runner.batch.LogOutput logOutput, @Nullable List<Object> extensions) {
- EnvironmentInformation env = new EnvironmentInformation(properties.getProperty("sonarRunner.app"), properties.getProperty("sonarRunner.appVersion"));
- Batch.Builder builder = Batch.builder()
- .setEnvironment(env)
- .setBootstrapProperties((Map) properties);
-
- if (extensions != null) {
- builder.addComponents(extensions);
- }
-
- if (logOutput != null) {
- // Do that is a separate class to avoid NoClassDefFoundError for org/sonar/batch/bootstrapper/LogOutput
- Compatibility.setLogOutputFor5dot2(builder, logOutput);
- }
-
- return builder.build();
- }
-
/**
* This method exists for backward compatibility with SonarQube < 5.2.
*/
@Override
public void executeOldVersion(Properties properties, List<Object> extensions) {
- createBatch(properties, null, extensions).execute();
+ factory.createBatch(properties, null, extensions).execute();
}
@Override
diff --git a/sonar-runner-batch/src/main/java/org/sonar/runner/batch/DefaultBatchFactory.java b/sonar-runner-batch/src/main/java/org/sonar/runner/batch/DefaultBatchFactory.java
new file mode 100644
index 0000000..e7d1a06
--- /dev/null
+++ b/sonar-runner-batch/src/main/java/org/sonar/runner/batch/DefaultBatchFactory.java
@@ -0,0 +1,49 @@
+/*
+ * SonarQube Runner - Batch
+ * Copyright (C) 2011 SonarSource
+ * sonarqube@googlegroups.com
+ *
+ * This program 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.
+ *
+ * This program 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 02
+ */
+package org.sonar.runner.batch;
+
+import org.picocontainer.annotations.Nullable;
+import org.sonar.batch.bootstrapper.Batch;
+import org.sonar.batch.bootstrapper.EnvironmentInformation;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+class DefaultBatchFactory implements BatchFactory {
+ @Override
+ public Batch createBatch(Properties properties, @Nullable final org.sonar.runner.batch.LogOutput logOutput, @Nullable List<Object> extensions) {
+ EnvironmentInformation env = new EnvironmentInformation(properties.getProperty("sonarRunner.app"), properties.getProperty("sonarRunner.appVersion"));
+ Batch.Builder builder = Batch.builder()
+ .setEnvironment(env)
+ .setBootstrapProperties((Map) properties);
+
+ if (extensions != null) {
+ builder.addComponents(extensions);
+ }
+
+ if (logOutput != null) {
+ // Do that is a separate class to avoid NoClassDefFoundError for org/sonar/batch/bootstrapper/LogOutput
+ Compatibility.setLogOutputFor5dot2(builder, logOutput);
+ }
+
+ return builder.build();
+ }
+}
diff --git a/sonar-runner-batch/src/main/java/org/sonar/runner/batch/package-info.java b/sonar-runner-batch/src/main/java/org/sonar/runner/batch/package-info.java
new file mode 100644
index 0000000..525879d
--- /dev/null
+++ b/sonar-runner-batch/src/main/java/org/sonar/runner/batch/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * SonarQube Runner - Batch
+ * Copyright (C) 2011 SonarSource
+ * sonarqube@googlegroups.com
+ *
+ * This program 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.
+ *
+ * This program 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 02
+ */
+package org.sonar.runner.batch;
diff --git a/sonar-runner-batch/src/test/java/org/sonar/runner/batch/BatchIsolatedLauncherTest.java b/sonar-runner-batch/src/test/java/org/sonar/runner/batch/BatchIsolatedLauncherTest.java
new file mode 100644
index 0000000..d222a6d
--- /dev/null
+++ b/sonar-runner-batch/src/test/java/org/sonar/runner/batch/BatchIsolatedLauncherTest.java
@@ -0,0 +1,107 @@
+/*
+ * SonarQube Runner - Batch
+ * Copyright (C) 2011 SonarSource
+ * sonarqube@googlegroups.com
+ *
+ * This program 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.
+ *
+ * This program 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 02
+ */
+package org.sonar.runner.batch;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.batch.bootstrapper.Batch;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import static org.mockito.Matchers.eq;
+
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyListOf;
+import static org.mockito.Mockito.mock;
+
+public class BatchIsolatedLauncherTest {
+ private Batch batch;
+ private BatchFactory factory;
+ private BatchIsolatedLauncher launcher;
+
+ @Before
+ public void setUp() {
+ factory = mock(BatchFactory.class);
+ batch = mock(Batch.class);
+ when(factory.createBatch(any(Properties.class), any(LogOutput.class), anyListOf(Object.class))).thenReturn(batch);
+ launcher = new BatchIsolatedLauncher(factory);
+ }
+
+ @Test
+ public void executeOld() {
+ Properties prop = new Properties();
+ List<Object> list = new LinkedList<>();
+
+ launcher.executeOldVersion(prop, list);
+
+ verify(factory).createBatch(prop, null, list);
+ verify(batch).execute();
+
+ verifyNoMoreInteractions(batch);
+ verifyNoMoreInteractions(factory);
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void executeWithoutStart() {
+ IssueListener issueListener = mock(IssueListener.class);
+ Properties prop = new Properties();
+ launcher.execute(prop, issueListener);
+ }
+
+ @Test
+ public void executeWithListener() {
+ IssueListener issueListener = mock(IssueListener.class);
+ Properties prop = new Properties();
+
+ launcher.start(null, null, true);
+ launcher.execute(prop, issueListener);
+
+ verify(batch).start(true);
+ verify(batch).executeTask(eq((Map) prop), any(org.sonar.batch.bootstrapper.IssueListener.class));
+
+ verifyNoMoreInteractions(batch);
+ }
+
+ @Test
+ public void proxy() {
+ Properties prop = new Properties();
+
+ launcher.start(prop, null, true);
+ launcher.syncProject("proj");
+ launcher.execute(prop);
+ launcher.stop();
+
+ verify(factory).createBatch(any(Properties.class), any(LogOutput.class), anyListOf(Object.class));
+ verify(batch).start(true);
+ verify(batch).syncProject("proj");
+ verify(batch).executeTask((Map) prop);
+ verify(batch).stop();
+
+ verifyNoMoreInteractions(batch);
+ verifyNoMoreInteractions(factory);
+ }
+
+}
diff --git a/sonar-runner-batch/src/test/java/org/sonar/runner/batch/IsolatedLauncherTest.java b/sonar-runner-batch/src/test/java/org/sonar/runner/batch/DefaultBatchFactoryTest.java
index 7ea9227..4574940 100644
--- a/sonar-runner-batch/src/test/java/org/sonar/runner/batch/IsolatedLauncherTest.java
+++ b/sonar-runner-batch/src/test/java/org/sonar/runner/batch/DefaultBatchFactoryTest.java
@@ -25,10 +25,10 @@ import org.sonar.batch.bootstrapper.Batch;
import static org.fest.assertions.Assertions.assertThat;
-public class IsolatedLauncherTest {
+public class DefaultBatchFactoryTest {
- Properties props = new Properties();
- BatchIsolatedLauncher launcher = new BatchIsolatedLauncher();
+ private Properties props = new Properties();
+ private BatchFactory factory = new DefaultBatchFactory();
@Test
public void should_create_batch() {
@@ -37,7 +37,7 @@ public class IsolatedLauncherTest {
props.setProperty("sonar.projectName", "Sample");
props.setProperty("sonar.projectVersion", "1.0");
props.setProperty("sonar.sources", "src");
- Batch batch = launcher.createBatch(props, null, null);
+ Batch batch = factory.createBatch(props, null, null);
assertThat(batch).isNotNull();
}