aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sonar-core/src/main/java/org/sonar/core/plugins/DefaultPluginMetadata.java45
-rw-r--r--sonar-core/src/main/java/org/sonar/core/plugins/PluginInstaller.java1
-rw-r--r--sonar-core/src/test/java/org/sonar/core/plugins/DefaultPluginMetadataTest.java92
-rw-r--r--sonar-core/src/test/java/org/sonar/core/plugins/PluginInstallerTest.java77
-rw-r--r--sonar-core/src/test/resources/org/sonar/core/plugins/checkstyle-extension.xml (renamed from sonar-core/src/test/resources/org/sonar/core/plugins/PluginInstallerTest/shouldCopyRuleExtensionsOnServerSide/checkstyle-extension.xml)0
-rw-r--r--sonar-core/src/test/resources/org/sonar/core/plugins/sonar-switch-off-violations-plugin-1.1.jarbin0 -> 12689 bytes
-rw-r--r--sonar-server/src/main/java/org/sonar/server/plugins/PluginDeployer.java49
-rw-r--r--sonar-server/src/test/java/org/sonar/server/plugins/PluginDeployerTest.java62
-rw-r--r--sonar-server/src/test/resources/org/sonar/server/plugins/PluginDeployerTest/should_fail_on_plugin_depending_on_more_recent_sonar/extensions/plugins/sonar-switch-off-violations-plugin-1.1.jarbin0 -> 12689 bytes
9 files changed, 218 insertions, 108 deletions
diff --git a/sonar-core/src/main/java/org/sonar/core/plugins/DefaultPluginMetadata.java b/sonar-core/src/main/java/org/sonar/core/plugins/DefaultPluginMetadata.java
index f9f65033cd8..22ff29fadb9 100644
--- a/sonar-core/src/main/java/org/sonar/core/plugins/DefaultPluginMetadata.java
+++ b/sonar-core/src/main/java/org/sonar/core/plugins/DefaultPluginMetadata.java
@@ -19,6 +19,10 @@
*/
package org.sonar.core.plugins;
+import com.google.common.base.CharMatcher;
+import com.google.common.base.Splitter;
+import com.google.common.collect.ComparisonChain;
+import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
@@ -35,6 +39,7 @@ public class DefaultPluginMetadata implements PluginMetadata, Comparable<PluginM
private String[] pathsToInternalDeps = new String[0];
private String key;
private String version;
+ private String sonarVersion;
private String name;
private String mainClass;
private String description;
@@ -166,6 +171,46 @@ public class DefaultPluginMetadata implements PluginMetadata, Comparable<PluginM
return this;
}
+ public String getSonarVersion() {
+ return sonarVersion;
+ }
+
+ public DefaultPluginMetadata setSonarVersion(String sonarVersion) {
+ this.sonarVersion = sonarVersion;
+ return this;
+ }
+
+ /**
+ * Find out if this plugin is compatible with a given version of Sonar.
+ * The version of sonar must be greater than or equal to the minimal version
+ * needed by the plugin.
+ *
+ * @param sonarVersion
+ * @return <code>true</code> if the plugin is compatible
+ */
+ public boolean isCompatibleWith(String sonarVersion) {
+ if (null == this.sonarVersion) {
+ return true; // Plugins without sonar version are so old, they are compatible with a version containing this code
+ }
+ if (null == sonarVersion) {
+ return true;
+ }
+
+ return ComparisonChain.start()
+ .compare(part(sonarVersion, 0), part(this.sonarVersion, 0))
+ .compare(part(sonarVersion, 1), part(this.sonarVersion, 1))
+ .compare(part(sonarVersion, 2), part(this.sonarVersion, 2))
+ .result() >= 0;
+ }
+
+ private static int part(String version, int index) {
+ Iterable<String> parts = Splitter.on('.').split(version);
+ String part = Iterables.get(parts, index, "0");
+ String onlyDigits = CharMatcher.DIGIT.retainFrom(part);
+
+ return Integer.parseInt(onlyDigits);
+ }
+
public String getHomepage() {
return homepage;
}
diff --git a/sonar-core/src/main/java/org/sonar/core/plugins/PluginInstaller.java b/sonar-core/src/main/java/org/sonar/core/plugins/PluginInstaller.java
index 5566a0e0ae0..d0289f4a82f 100644
--- a/sonar-core/src/main/java/org/sonar/core/plugins/PluginInstaller.java
+++ b/sonar-core/src/main/java/org/sonar/core/plugins/PluginInstaller.java
@@ -116,6 +116,7 @@ public class PluginInstaller {
metadata.setOrganizationUrl(manifest.getOrganizationUrl());
metadata.setMainClass(manifest.getMainClass());
metadata.setVersion(manifest.getVersion());
+ metadata.setSonarVersion(manifest.getSonarVersion());
metadata.setHomepage(manifest.getHomepage());
metadata.setPathsToInternalDeps(manifest.getDependencies());
metadata.setUseChildFirstClassLoader(manifest.isUseChildFirstClassLoader());
diff --git a/sonar-core/src/test/java/org/sonar/core/plugins/DefaultPluginMetadataTest.java b/sonar-core/src/test/java/org/sonar/core/plugins/DefaultPluginMetadataTest.java
index 27cf28eea34..02053827323 100644
--- a/sonar-core/src/test/java/org/sonar/core/plugins/DefaultPluginMetadataTest.java
+++ b/sonar-core/src/test/java/org/sonar/core/plugins/DefaultPluginMetadataTest.java
@@ -19,15 +19,15 @@
*/
package org.sonar.core.plugins;
-import org.hamcrest.core.Is;
import org.junit.Test;
import org.sonar.api.platform.PluginMetadata;
import java.io.File;
import java.util.Arrays;
+import java.util.List;
-import static org.hamcrest.CoreMatchers.*;
-import static org.junit.Assert.assertThat;
+import static com.google.common.collect.Ordering.natural;
+import static org.fest.assertions.Assertions.assertThat;
public class DefaultPluginMetadataTest {
@@ -41,19 +41,25 @@ public class DefaultPluginMetadataTest {
.setMainClass("org.Main")
.setOrganization("SonarSource")
.setOrganizationUrl("http://sonarsource.org")
- .setVersion("1.1");
-
- assertThat(metadata.getKey(), Is.is("checkstyle"));
- assertThat(metadata.getLicense(), Is.is("LGPL"));
- assertThat(metadata.getDescription(), Is.is("description"));
- assertThat(metadata.getHomepage(), Is.is("http://home"));
- assertThat(metadata.getMainClass(), Is.is("org.Main"));
- assertThat(metadata.getOrganization(), Is.is("SonarSource"));
- assertThat(metadata.getOrganizationUrl(), Is.is("http://sonarsource.org"));
- assertThat(metadata.getVersion(), Is.is("1.1"));
- assertThat(metadata.getBasePlugin(), nullValue());
- assertThat(metadata.getFile(), not(nullValue()));
- assertThat(metadata.getDeployedFiles().size(), is(0));
+ .setVersion("1.1")
+ .setSonarVersion("3.0")
+ .setUseChildFirstClassLoader(true)
+ .setCore(false);
+
+ assertThat(metadata.getKey()).isEqualTo("checkstyle");
+ assertThat(metadata.getLicense()).isEqualTo("LGPL");
+ assertThat(metadata.getDescription()).isEqualTo("description");
+ assertThat(metadata.getHomepage()).isEqualTo("http://home");
+ assertThat(metadata.getMainClass()).isEqualTo("org.Main");
+ assertThat(metadata.getOrganization()).isEqualTo("SonarSource");
+ assertThat(metadata.getOrganizationUrl()).isEqualTo("http://sonarsource.org");
+ assertThat(metadata.getVersion()).isEqualTo("1.1");
+ assertThat(metadata.getSonarVersion()).isEqualTo("3.0");
+ assertThat(metadata.isUseChildFirstClassLoader()).isTrue();
+ assertThat(metadata.isCore()).isFalse();
+ assertThat(metadata.getBasePlugin()).isNull();
+ assertThat(metadata.getFile()).isNotNull();
+ assertThat(metadata.getDeployedFiles()).isEmpty();
}
@Test
@@ -61,16 +67,16 @@ public class DefaultPluginMetadataTest {
DefaultPluginMetadata metadata = DefaultPluginMetadata.create(new File("sonar-checkstyle-plugin.jar"))
.addDeployedFile(new File("foo.jar"))
.addDeployedFile(new File("bar.jar"));
- assertThat(metadata.getDeployedFiles().size(), is(2));
+
+ assertThat(metadata.getDeployedFiles()).hasSize(2);
}
@Test
public void testInternalPathToDependencies() {
DefaultPluginMetadata metadata = DefaultPluginMetadata.create(new File("sonar-checkstyle-plugin.jar"))
- .setPathsToInternalDeps(new String[]{"META-INF/lib/commons-lang.jar", "META-INF/lib/commons-io.jar"});
- assertThat(metadata.getPathsToInternalDeps().length, is(2));
- assertThat(metadata.getPathsToInternalDeps()[0], is("META-INF/lib/commons-lang.jar"));
- assertThat(metadata.getPathsToInternalDeps()[1], is("META-INF/lib/commons-io.jar"));
+ .setPathsToInternalDeps(new String[] {"META-INF/lib/commons-lang.jar", "META-INF/lib/commons-io.jar"});
+
+ assertThat(metadata.getPathsToInternalDeps()).containsOnly("META-INF/lib/commons-lang.jar", "META-INF/lib/commons-io.jar");
}
@Test
@@ -78,23 +84,49 @@ public class DefaultPluginMetadataTest {
DefaultPluginMetadata checkstyle = DefaultPluginMetadata.create(new File("sonar-checkstyle-plugin.jar")).setKey("checkstyle");
PluginMetadata pmd = DefaultPluginMetadata.create(new File("sonar-pmd-plugin.jar")).setKey("pmd");
- assertThat(checkstyle.equals(pmd), is(false));
- assertThat(checkstyle.equals(checkstyle), is(true));
- assertThat(checkstyle.equals(DefaultPluginMetadata.create(new File("sonar-checkstyle-plugin.jar")).setKey("checkstyle")), is(true));
+ assertThat(checkstyle).isEqualTo(checkstyle);
+ assertThat(checkstyle).isEqualTo(DefaultPluginMetadata.create(new File("sonar-checkstyle-plugin.jar")).setKey("checkstyle"));
+ assertThat(checkstyle).isNotEqualTo(pmd);
}
@Test
public void shouldCompare() {
- PluginMetadata checkstyle = DefaultPluginMetadata.create(new File("sonar-checkstyle-plugin.jar"))
+ DefaultPluginMetadata checkstyle = DefaultPluginMetadata.create(new File("sonar-checkstyle-plugin.jar"))
.setKey("checkstyle")
.setName("Checkstyle");
- PluginMetadata pmd = DefaultPluginMetadata.create(new File("sonar-pmd-plugin.jar"))
+ DefaultPluginMetadata pmd = DefaultPluginMetadata.create(new File("sonar-pmd-plugin.jar"))
.setKey("pmd")
.setName("PMD");
+ List<DefaultPluginMetadata> plugins = Arrays.asList(pmd, checkstyle);
+
+ assertThat(natural().sortedCopy(plugins)).onProperty("key").containsExactly("checkstyle", "pmd");
+ }
+
+ @Test
+ public void should_check_compatibility_with_sonar_version() {
+ assertThat(pluginWithVersion("1.1").isCompatibleWith("1.1")).isTrue();
+ assertThat(pluginWithVersion("1.1").isCompatibleWith("1.1.0")).isTrue();
+ assertThat(pluginWithVersion("1.0").isCompatibleWith("1.0.0")).isTrue();
+
+ assertThat(pluginWithVersion("1.0").isCompatibleWith("1.1")).isTrue();
+ assertThat(pluginWithVersion("1.1.1").isCompatibleWith("1.1.2")).isTrue();
+ assertThat(pluginWithVersion("2.0").isCompatibleWith("2.1.0")).isTrue();
+
+ assertThat(pluginWithVersion("1.1").isCompatibleWith("1.0")).isFalse();
+ assertThat(pluginWithVersion("2.0.1").isCompatibleWith("2.0.0")).isFalse();
+ assertThat(pluginWithVersion("2.10").isCompatibleWith("2.1")).isFalse();
+ assertThat(pluginWithVersion("10.10").isCompatibleWith("2.2")).isFalse();
+
+ assertThat(pluginWithVersion("1.1-SNAPSHOT").isCompatibleWith("1.0")).isFalse();
+ assertThat(pluginWithVersion("1.1-SNAPSHOT").isCompatibleWith("1.1")).isTrue();
+ assertThat(pluginWithVersion("1.1-SNAPSHOT").isCompatibleWith("1.2")).isTrue();
+ assertThat(pluginWithVersion("1.0.1-SNAPSHOT").isCompatibleWith("1.0")).isFalse();
+
+ assertThat(pluginWithVersion(null).isCompatibleWith("0")).isTrue();
+ assertThat(pluginWithVersion(null).isCompatibleWith("3.1")).isTrue();
+ }
- PluginMetadata[] array = {pmd, checkstyle};
- Arrays.sort(array);
- assertThat(array[0].getKey(), is("checkstyle"));
- assertThat(array[1].getKey(), is("pmd"));
+ static DefaultPluginMetadata pluginWithVersion(String version) {
+ return DefaultPluginMetadata.create(null).setSonarVersion(version);
}
}
diff --git a/sonar-core/src/test/java/org/sonar/core/plugins/PluginInstallerTest.java b/sonar-core/src/test/java/org/sonar/core/plugins/PluginInstallerTest.java
index 9afc9c9de17..e9a893c48be 100644
--- a/sonar-core/src/test/java/org/sonar/core/plugins/PluginInstallerTest.java
+++ b/sonar-core/src/test/java/org/sonar/core/plugins/PluginInstallerTest.java
@@ -20,86 +20,95 @@
package org.sonar.core.plugins;
import org.apache.commons.io.FileUtils;
+import org.junit.ClassRule;
import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
import java.io.File;
import java.io.IOException;
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.nullValue;
-import static org.junit.Assert.assertThat;
+import static org.fest.assertions.Assertions.assertThat;
public class PluginInstallerTest {
- private PluginInstaller extractor= new PluginInstaller();
+ private PluginInstaller extractor = new PluginInstaller();
+
+ @ClassRule
+ public static TemporaryFolder temporaryFolder = new TemporaryFolder();
@Test
public void shouldExtractMetadata() {
DefaultPluginMetadata metadata = extractor.extractMetadata(getFile("sonar-checkstyle-plugin-2.8.jar"), true);
- assertThat(metadata.getKey(), is("checkstyle"));
- assertThat(metadata.getBasePlugin(), nullValue());
- assertThat(metadata.getName(), is("Checkstyle"));
- assertThat(metadata.isCore(), is(true));
- assertThat(metadata.getFile().getName(), is("sonar-checkstyle-plugin-2.8.jar"));
+
+ assertThat(metadata.getKey()).isEqualTo("checkstyle");
+ assertThat(metadata.getBasePlugin()).isNull();
+ assertThat(metadata.getName()).isEqualTo("Checkstyle");
+ assertThat(metadata.isCore()).isEqualTo(true);
+ assertThat(metadata.getFile().getName()).isEqualTo("sonar-checkstyle-plugin-2.8.jar");
+ assertThat(metadata.getVersion()).isEqualTo("2.8");
+ }
+
+ @Test
+ public void should_read_sonar_version() {
+ DefaultPluginMetadata metadata = extractor.extractMetadata(getFile("sonar-switch-off-violations-plugin-1.1.jar"), false);
+
+ assertThat(metadata.getVersion()).isEqualTo("1.1");
+ assertThat(metadata.getSonarVersion()).isEqualTo("2.5");
}
@Test
public void shouldExtractDeprecatedMetadata() {
DefaultPluginMetadata metadata = extractor.extractMetadata(getFile("sonar-emma-plugin-0.3.jar"), false);
- assertThat(metadata.getKey(), is("emma"));
- assertThat(metadata.getBasePlugin(), nullValue());
- assertThat(metadata.getName(), is("Emma"));
+
+ assertThat(metadata.getKey()).isEqualTo("emma");
+ assertThat(metadata.getBasePlugin()).isNull();
+ assertThat(metadata.getName()).isEqualTo("Emma");
}
@Test
public void shouldExtractExtensionMetadata() {
DefaultPluginMetadata metadata = extractor.extractMetadata(getFile("sonar-checkstyle-extensions-plugin-0.1-SNAPSHOT.jar"), true);
- assertThat(metadata.getKey(), is("checkstyleextensions"));
- assertThat(metadata.getBasePlugin(), is("checkstyle"));
+
+ assertThat(metadata.getKey()).isEqualTo("checkstyleextensions");
+ assertThat(metadata.getBasePlugin()).isEqualTo("checkstyle");
}
@Test
public void shouldCopyAndExtractDependencies() throws IOException {
- File toDir = new File("target/test-tmp/PluginInstallerTest/shouldCopyAndExtractDependencies");
- FileUtils.forceMkdir(toDir);
- FileUtils.cleanDirectory(toDir);
+ File toDir = temporaryFolder.newFolder();
DefaultPluginMetadata metadata = extractor.install(getFile("sonar-checkstyle-plugin-2.8.jar"), true, null, toDir);
- assertThat(metadata.getKey(), is("checkstyle"));
- assertThat(new File(toDir, "sonar-checkstyle-plugin-2.8.jar").exists(), is(true));
- assertThat(new File(toDir, "META-INF/lib/checkstyle-5.1.jar").exists(), is(true));
+ assertThat(metadata.getKey()).isEqualTo("checkstyle");
+ assertThat(new File(toDir, "sonar-checkstyle-plugin-2.8.jar")).exists();
+ assertThat(new File(toDir, "META-INF/lib/checkstyle-5.1.jar")).exists();
}
@Test
public void shouldExtractOnlyDependencies() throws IOException {
- File toDir = new File("target/test-tmp/PluginInstallerTest/shouldExtractOnlyDependencies");
- FileUtils.forceMkdir(toDir);
- FileUtils.cleanDirectory(toDir);
+ File toDir = temporaryFolder.newFolder();
extractor.install(getFile("sonar-checkstyle-plugin-2.8.jar"), true, null, toDir);
- assertThat(new File(toDir, "sonar-checkstyle-plugin-2.8.jar").exists(), is(true));
- assertThat(new File(toDir, "META-INF/MANIFEST.MF").exists(), is(false));
- assertThat(new File(toDir, "org/sonar/plugins/checkstyle/CheckstyleVersion.class").exists(), is(false));
+ assertThat(new File(toDir, "sonar-checkstyle-plugin-2.8.jar")).exists();
+ assertThat(new File(toDir, "META-INF/MANIFEST.MF")).doesNotExist();
+ assertThat(new File(toDir, "org/sonar/plugins/checkstyle/CheckstyleVersion.class")).doesNotExist();
}
@Test
public void shouldCopyRuleExtensionsOnServerSide() throws IOException {
- File toDir = new File("target/test-tmp/PluginInstallerTest/shouldCopyRuleExtensionsOnServerSide");
- FileUtils.forceMkdir(toDir);
- FileUtils.cleanDirectory(toDir);
+ File toDir = temporaryFolder.newFolder();
DefaultPluginMetadata metadata = DefaultPluginMetadata.create(getFile("sonar-checkstyle-plugin-2.8.jar"))
.setKey("checkstyle")
- .addDeprecatedExtension(getFile("PluginInstallerTest/shouldCopyRuleExtensionsOnServerSide/checkstyle-extension.xml"));
+ .addDeprecatedExtension(getFile("checkstyle-extension.xml"));
extractor.install(metadata, toDir);
- assertThat(new File(toDir, "sonar-checkstyle-plugin-2.8.jar").exists(), is(true));
- assertThat(new File(toDir, "checkstyle-extension.xml").exists(), is(true));
+ assertThat(new File(toDir, "sonar-checkstyle-plugin-2.8.jar")).exists();
+ assertThat(new File(toDir, "checkstyle-extension.xml")).exists();
}
- private File getFile(String filename) {
- return FileUtils.toFile(getClass().getResource("/org/sonar/core/plugins/" + filename));
+ static File getFile(String filename) {
+ return FileUtils.toFile(PluginInstallerTest.class.getResource("/org/sonar/core/plugins/" + filename));
}
}
diff --git a/sonar-core/src/test/resources/org/sonar/core/plugins/PluginInstallerTest/shouldCopyRuleExtensionsOnServerSide/checkstyle-extension.xml b/sonar-core/src/test/resources/org/sonar/core/plugins/checkstyle-extension.xml
index 75a263db3c3..75a263db3c3 100644
--- a/sonar-core/src/test/resources/org/sonar/core/plugins/PluginInstallerTest/shouldCopyRuleExtensionsOnServerSide/checkstyle-extension.xml
+++ b/sonar-core/src/test/resources/org/sonar/core/plugins/checkstyle-extension.xml
diff --git a/sonar-core/src/test/resources/org/sonar/core/plugins/sonar-switch-off-violations-plugin-1.1.jar b/sonar-core/src/test/resources/org/sonar/core/plugins/sonar-switch-off-violations-plugin-1.1.jar
new file mode 100644
index 00000000000..8044dff8988
--- /dev/null
+++ b/sonar-core/src/test/resources/org/sonar/core/plugins/sonar-switch-off-violations-plugin-1.1.jar
Binary files differ
diff --git a/sonar-server/src/main/java/org/sonar/server/plugins/PluginDeployer.java b/sonar-server/src/main/java/org/sonar/server/plugins/PluginDeployer.java
index 79618d14160..775408ca64c 100644
--- a/sonar-server/src/main/java/org/sonar/server/plugins/PluginDeployer.java
+++ b/sonar-server/src/main/java/org/sonar/server/plugins/PluginDeployer.java
@@ -19,6 +19,7 @@
*/
package org.sonar.server.plugins;
+import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.io.FileUtils;
@@ -27,7 +28,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.ServerComponent;
import org.sonar.api.platform.PluginMetadata;
-import org.sonar.api.utils.Logs;
+import org.sonar.api.platform.Server;
import org.sonar.api.utils.SonarException;
import org.sonar.api.utils.TimeProfiler;
import org.sonar.core.plugins.DefaultPluginMetadata;
@@ -45,15 +46,17 @@ public class PluginDeployer implements ServerComponent {
private static final Logger LOG = LoggerFactory.getLogger(PluginDeployer.class);
+ private final Server server;
private final DefaultServerFileSystem fileSystem;
- private final Map<String, PluginMetadata> pluginByKeys = Maps.newHashMap();
private final PluginInstaller installer;
+ private final Map<String, PluginMetadata> pluginByKeys = Maps.newHashMap();
- public PluginDeployer(DefaultServerFileSystem fileSystem) {
- this(fileSystem, new PluginInstaller());
+ public PluginDeployer(Server server, DefaultServerFileSystem fileSystem) {
+ this(server, fileSystem, new PluginInstaller());
}
- PluginDeployer(DefaultServerFileSystem fileSystem, PluginInstaller installer) {
+ PluginDeployer(Server server, DefaultServerFileSystem fileSystem, PluginInstaller installer) {
+ this.server = server;
this.fileSystem = fileSystem;
this.installer = installer;
}
@@ -91,19 +94,20 @@ public class PluginDeployer implements ServerComponent {
private void registerPlugin(File file, boolean isCore, boolean canDelete) {
DefaultPluginMetadata metadata = installer.extractMetadata(file, isCore);
- if (StringUtils.isNotBlank(metadata.getKey())) {
- PluginMetadata existing = pluginByKeys.get(metadata.getKey());
- if (existing != null) {
- if (canDelete) {
- FileUtils.deleteQuietly(existing.getFile());
- Logs.INFO.info("Plugin " + metadata.getKey() + " replaced by new version");
-
- } else {
- throw new ServerStartException("Found two plugins with the same key '" + metadata.getKey() + "': " + metadata.getFile().getName() + " and "
- + existing.getFile().getName());
- }
- }
- pluginByKeys.put(metadata.getKey(), metadata);
+ if (StringUtils.isBlank(metadata.getKey())) {
+ return;
+ }
+
+ PluginMetadata existing = pluginByKeys.put(metadata.getKey(), metadata);
+
+ if ((existing != null) && !canDelete) {
+ throw new ServerStartException("Found two plugins with the same key '" + metadata.getKey() + "': " + metadata.getFile().getName() + " and "
+ + existing.getFile().getName());
+ }
+
+ if (existing != null) {
+ FileUtils.deleteQuietly(existing.getFile());
+ LOG.info("Plugin " + metadata.getKey() + " replaced by new version");
}
}
@@ -186,9 +190,13 @@ public class PluginDeployer implements ServerComponent {
}
private void deploy(DefaultPluginMetadata plugin) {
- try {
- LOG.debug("Deploy plugin " + plugin);
+ LOG.debug("Deploy plugin " + plugin);
+ Preconditions.checkState(plugin.isCompatibleWith(server.getVersion()),
+ "Plugin %s needs a more recent version of Sonar than %s. At least %s is expected",
+ plugin.getKey(), server.getVersion(), plugin.getSonarVersion());
+
+ try {
File pluginDeployDir = new File(fileSystem.getDeployedPluginsDir(), plugin.getKey());
FileUtils.forceMkdir(pluginDeployDir);
FileUtils.cleanDirectory(pluginDeployDir);
@@ -199,7 +207,6 @@ public class PluginDeployer implements ServerComponent {
}
installer.install(plugin, pluginDeployDir);
-
} catch (IOException e) {
throw new RuntimeException("Fail to deploy the plugin " + plugin, e);
}
diff --git a/sonar-server/src/test/java/org/sonar/server/plugins/PluginDeployerTest.java b/sonar-server/src/test/java/org/sonar/server/plugins/PluginDeployerTest.java
index 6adefb336f9..d134a23ce07 100644
--- a/sonar-server/src/test/java/org/sonar/server/plugins/PluginDeployerTest.java
+++ b/sonar-server/src/test/java/org/sonar/server/plugins/PluginDeployerTest.java
@@ -19,12 +19,13 @@
*/
package org.sonar.server.plugins;
-import org.hamcrest.core.Is;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.ExpectedException;
import org.junit.rules.TestName;
import org.sonar.api.platform.PluginMetadata;
+import org.sonar.api.platform.Server;
import org.sonar.core.plugins.PluginInstaller;
import org.sonar.server.platform.DefaultServerFileSystem;
import org.sonar.server.platform.ServerStartException;
@@ -32,8 +33,9 @@ import org.sonar.test.TestUtils;
import java.io.File;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
public class PluginDeployerTest {
@@ -42,17 +44,22 @@ public class PluginDeployerTest {
private File homeDir;
private File deployDir;
private PluginDeployer deployer;
+ private Server server = mock(Server.class);
@Rule
public TestName name = new TestName();
+ @Rule
+ public ExpectedException exception = ExpectedException.none();
+
@Before
public void start() {
+ when(server.getVersion()).thenReturn("3.1");
homeDir = TestUtils.getResource(PluginDeployerTest.class, name.getMethodName());
deployDir = TestUtils.getTestTempDir(PluginDeployerTest.class, name.getMethodName() + "/deploy");
fileSystem = new DefaultServerFileSystem(null, homeDir, deployDir);
extractor = new PluginInstaller();
- deployer = new PluginDeployer(fileSystem, extractor);
+ deployer = new PluginDeployer(server, fileSystem, extractor);
}
@Test
@@ -60,18 +67,18 @@ public class PluginDeployerTest {
deployer.start();
// check that the plugin is registered
- assertThat(deployer.getMetadata().size(), Is.is(1)); // no more checkstyle
+ assertThat(deployer.getMetadata()).hasSize(1); // no more checkstyle
PluginMetadata plugin = deployer.getMetadata("foo");
- assertThat(plugin.getName(), is("Foo"));
- assertThat(plugin.getDeployedFiles().size(), is(1));
- assertThat(plugin.isCore(), is(false));
- assertThat(plugin.isUseChildFirstClassLoader(), is(false));
+ assertThat(plugin.getName()).isEqualTo("Foo");
+ assertThat(plugin.getDeployedFiles()).hasSize(1);
+ assertThat(plugin.isCore()).isFalse();
+ assertThat(plugin.isUseChildFirstClassLoader()).isFalse();
// check that the file is deployed
File deployedJar = new File(deployDir, "plugins/foo/foo-plugin.jar");
- assertThat(deployedJar.exists(), is(true));
- assertThat(deployedJar.isFile(), is(true));
+ assertThat(deployedJar.exists()).isTrue();
+ assertThat(deployedJar.isFile()).isTrue();
}
@Test
@@ -79,16 +86,16 @@ public class PluginDeployerTest {
deployer.start();
// check that the plugin is registered
- assertThat(deployer.getMetadata().size(), Is.is(1)); // no more checkstyle
+ assertThat(deployer.getMetadata()).hasSize(1); // no more checkstyle
PluginMetadata plugin = deployer.getMetadata("buildbreaker");
- assertThat(plugin.isCore(), is(false));
- assertThat(plugin.isUseChildFirstClassLoader(), is(false));
+ assertThat(plugin.isCore()).isFalse();
+ assertThat(plugin.isUseChildFirstClassLoader()).isFalse();
// check that the file is deployed
File deployedJar = new File(deployDir, "plugins/buildbreaker/sonar-build-breaker-plugin-0.1.jar");
- assertThat(deployedJar.exists(), is(true));
- assertThat(deployedJar.isFile(), is(true));
+ assertThat(deployedJar.exists()).isTrue();
+ assertThat(deployedJar.isFile()).isTrue();
}
@Test
@@ -96,24 +103,34 @@ public class PluginDeployerTest {
deployer.start();
// check that the plugin is registered
- assertThat(deployer.getMetadata().size(), Is.is(1)); // no more checkstyle
+ assertThat(deployer.getMetadata()).hasSize(1); // no more checkstyle
PluginMetadata plugin = deployer.getMetadata("foo");
- assertThat(plugin.getDeployedFiles().size(), is(2));
+ assertThat(plugin.getDeployedFiles()).hasSize(2);
File extFile = plugin.getDeployedFiles().get(1);
- assertThat(extFile.getName(), is("foo-extension.txt"));
+ assertThat(extFile.getName()).isEqualTo("foo-extension.txt");
// check that the extension file is deployed
File deployedJar = new File(deployDir, "plugins/foo/foo-extension.txt");
- assertThat(deployedJar.exists(), is(true));
- assertThat(deployedJar.isFile(), is(true));
+ assertThat(deployedJar.exists()).isTrue();
+ assertThat(deployedJar.isFile()).isTrue();
}
@Test
public void ignoreJarsWhichAreNotPlugins() {
deployer.start();
- assertThat(deployer.getMetadata().size(), Is.is(0));
+ assertThat(deployer.getMetadata()).isEmpty();
+ }
+
+ @Test
+ public void should_fail_on_plugin_depending_on_more_recent_sonar() {
+ when(server.getVersion()).thenReturn("2.0");
+
+ exception.expect(IllegalStateException.class);
+ exception.expectMessage("Plugin switchoffviolations needs a more recent version of Sonar than 2.0. At least 2.5 is expected");
+
+ deployer.start();
}
@Test(expected = ServerStartException.class)
@@ -125,5 +142,4 @@ public class PluginDeployerTest {
public void failIfTwoDeprecatedPluginsWithSameKey() {
deployer.start();
}
-
}
diff --git a/sonar-server/src/test/resources/org/sonar/server/plugins/PluginDeployerTest/should_fail_on_plugin_depending_on_more_recent_sonar/extensions/plugins/sonar-switch-off-violations-plugin-1.1.jar b/sonar-server/src/test/resources/org/sonar/server/plugins/PluginDeployerTest/should_fail_on_plugin_depending_on_more_recent_sonar/extensions/plugins/sonar-switch-off-violations-plugin-1.1.jar
new file mode 100644
index 00000000000..8044dff8988
--- /dev/null
+++ b/sonar-server/src/test/resources/org/sonar/server/plugins/PluginDeployerTest/should_fail_on_plugin_depending_on_more_recent_sonar/extensions/plugins/sonar-switch-off-violations-plugin-1.1.jar
Binary files differ