aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-server
diff options
context:
space:
mode:
authorDavid Gageot <david@gageot.net>2012-06-18 11:47:54 +0200
committerDavid Gageot <david@gageot.net>2012-06-18 12:39:50 +0200
commitba7439977f53e5c05f2c6cd52b907f6582a10bde (patch)
tree0d42f95864ec7e82bbdae465144bacc0307d752e /sonar-server
parent923bd083ff22f8bccf8fe3f698b2b82fa3347354 (diff)
downloadsonarqube-ba7439977f53e5c05f2c6cd52b907f6582a10bde.tar.gz
sonarqube-ba7439977f53e5c05f2c6cd52b907f6582a10bde.zip
SONAR-3516 Check minimal sonar version required by installed plugins
Plugin manifest declares the minimal required version of sonar. This version is verified at server startup. It prevents plugins from failing for API incompatibility reasons. Startup fails with a meaningful message.
Diffstat (limited to 'sonar-server')
-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
3 files changed, 67 insertions, 44 deletions
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