diff options
author | simonbrandhof <simon.brandhof@gmail.com> | 2011-06-10 00:15:37 +0200 |
---|---|---|
committer | simonbrandhof <simon.brandhof@gmail.com> | 2011-06-10 00:15:37 +0200 |
commit | d574f6dd70fefa9b2e9818c71ae58a51e934697c (patch) | |
tree | 76a7df2dc3c794c02fff45e9a517ccf560cc2351 /sonar-batch | |
parent | 39bca3376660b2ad6edbd4ec9fabf527a16ffe78 (diff) | |
download | sonarqube-d574f6dd70fefa9b2e9818c71ae58a51e934697c.tar.gz sonarqube-d574f6dd70fefa9b2e9818c71ae58a51e934697c.zip |
SONAR-2507 Batch must load plugins without connecting to database
Diffstat (limited to 'sonar-batch')
9 files changed, 230 insertions, 215 deletions
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ArtifactDownloader.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ArtifactDownloader.java index 6aa16b1c1e1..b8ae7330848 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ArtifactDownloader.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ArtifactDownloader.java @@ -19,18 +19,26 @@ */ package org.sonar.batch.bootstrap; +import com.google.common.collect.Lists; +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang.CharUtils; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.sonar.api.BatchComponent; import org.sonar.api.utils.HttpDownloader; import org.sonar.api.utils.SonarException; import org.sonar.batch.ServerMetadata; -import org.sonar.core.plugin.JpaPluginFile; import java.io.File; import java.net.URI; import java.net.URISyntaxException; +import java.util.List; public class ArtifactDownloader implements BatchComponent { + private static final Logger LOG = LoggerFactory.getLogger(ArtifactDownloader.class); + private HttpDownloader httpDownloader; private TempDirectories workingDirectories; private String baseUrl; @@ -45,6 +53,7 @@ public class ArtifactDownloader implements BatchComponent { String url = baseUrl + "/deploy/jdbc-driver.jar"; try { File jdbcDriver = new File(workingDirectories.getRoot(), "jdbc-driver.jar"); + LOG.info("Download JDBC driver to " + jdbcDriver); httpDownloader.download(new URI(url), jdbcDriver); return jdbcDriver; @@ -53,15 +62,87 @@ public class ArtifactDownloader implements BatchComponent { } } - public File downloadExtension(JpaPluginFile extension) { - File targetFile = new File(workingDirectories.getDir(extension.getPluginKey()), extension.getFilename()); - String url = baseUrl + "/deploy/plugins/" + extension.getPluginKey() + "/" + extension.getFilename(); + public File downloadPlugin(RemotePluginLocation remote) { + File targetFile = new File(workingDirectories.getDir("plugins/" + remote.getPluginKey()), remote.getFilename()); + String url = baseUrl + "/deploy/plugins/" + remote.getRemotePath(); try { + FileUtils.forceMkdir(targetFile.getParentFile()); + LOG.info("Download plugin to " + targetFile); httpDownloader.download(new URI(url), targetFile); return targetFile; - } catch (URISyntaxException e) { + } catch (Exception e) { throw new SonarException("Fail to download extension: " + url, e); } } + + public List<RemotePluginLocation> downloadPluginIndex() { + String url = baseUrl + "/deploy/plugins/index.txt"; + try { + String indexContent = httpDownloader.downloadPlainText(new URI(url), "UTF-8"); + String[] rows = StringUtils.split(indexContent, CharUtils.LF); + List<RemotePluginLocation> remoteLocations = Lists.newArrayList(); + for (String row : rows) { + remoteLocations.add(RemotePluginLocation.createFromRow(row)); + } + return remoteLocations; + + } catch (Exception e) { + throw new SonarException("Fail to download plugins index: " + url, e); + } + } + + public static final class RemotePluginLocation { + private String pluginKey; + private String remotePath; + private boolean core; + + private RemotePluginLocation(String pluginKey, String remotePath, boolean core) { + this.pluginKey = pluginKey; + this.remotePath = remotePath; + this.core = core; + } + + static RemotePluginLocation create(String key) { + return new RemotePluginLocation(key, null, false); + } + + static RemotePluginLocation createFromRow(String row) { + String[] fields = StringUtils.split(row, ","); + return new RemotePluginLocation(fields[0], fields[1], Boolean.parseBoolean(fields[2])); + } + + public String getPluginKey() { + return pluginKey; + } + + public String getRemotePath() { + return remotePath; + } + + public String getFilename() { + return StringUtils.substringAfterLast(remotePath, "/"); + } + + public boolean isCore() { + return core; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + RemotePluginLocation that = (RemotePluginLocation) o; + return pluginKey.equals(that.pluginKey); + } + + @Override + public int hashCode() { + return pluginKey.hashCode(); + } + } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchPluginRepository.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchPluginRepository.java index 99a7fc88aee..2452983bd11 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchPluginRepository.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchPluginRepository.java @@ -20,10 +20,9 @@ package org.sonar.batch.bootstrap; import com.google.common.base.Joiner; -import com.google.common.base.Predicate; -import com.google.common.collect.*; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; import org.apache.commons.configuration.Configuration; -import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -31,125 +30,64 @@ import org.sonar.api.CoreProperties; import org.sonar.api.Plugin; import org.sonar.api.Properties; import org.sonar.api.Property; +import org.sonar.api.platform.PluginMetadata; import org.sonar.api.platform.PluginRepository; -import org.sonar.api.utils.SonarException; -import org.sonar.core.classloaders.ClassLoadersCollection; -import org.sonar.core.plugin.JpaPlugin; -import org.sonar.core.plugin.JpaPluginDao; -import org.sonar.core.plugin.JpaPluginFile; +import org.sonar.core.plugins.PluginClassloaders; +import org.sonar.core.plugins.PluginFileExtractor; import java.io.File; -import java.net.MalformedURLException; -import java.net.URL; import java.util.*; public class BatchPluginRepository implements PluginRepository { private static final Logger LOG = LoggerFactory.getLogger(BatchPluginRepository.class); - private JpaPluginDao dao; private ArtifactDownloader artifactDownloader; private Map<String, Plugin> pluginsByKey; + private Map<String, PluginMetadata> metadataByKey; private Set<String> whiteList = null; private Set<String> blackList = null; + private PluginClassloaders classLoaders; - public BatchPluginRepository(JpaPluginDao dao, ArtifactDownloader artifactDownloader, Configuration configuration) { - this.dao = dao; + public BatchPluginRepository(ArtifactDownloader artifactDownloader, Configuration configuration) { this.artifactDownloader = artifactDownloader; - if (configuration.getString(CoreProperties.INCLUDE_PLUGINS)!=null) { + if (configuration.getString(CoreProperties.INCLUDE_PLUGINS) != null) { whiteList = Sets.newTreeSet(Arrays.asList(configuration.getStringArray(CoreProperties.INCLUDE_PLUGINS))); LOG.info("Include plugins: " + Joiner.on(", ").join(whiteList)); } - if (configuration.getString(CoreProperties.EXCLUDE_PLUGINS)!=null) { + if (configuration.getString(CoreProperties.EXCLUDE_PLUGINS) != null) { blackList = Sets.newTreeSet(Arrays.asList(configuration.getStringArray(CoreProperties.EXCLUDE_PLUGINS))); LOG.info("Exclude plugins: " + Joiner.on(", ").join(blackList)); } -// TODO reactivate somewhere else: LOG.info("Execution environment: {} {}", environment.getKey(), environment.getVersion()); + // TODO reactivate somewhere else: LOG.info("Execution environment: {} {}", environment.getKey(), environment.getVersion()); } public void start() { - List<JpaPlugin> plugins = filter(dao.getPlugins()); - LOG.debug("Starting plugins: " + Joiner.on(", ").join(plugins)); - doStart(plugins); + doStart(artifactDownloader.downloadPluginIndex()); } - List<JpaPlugin> filter(List<JpaPlugin> plugins) { - return ImmutableList.copyOf(Iterables.filter(plugins, new Predicate<JpaPlugin>() { - public boolean apply(JpaPlugin p) { - return isAccepted(p.getKey()) && (StringUtils.isBlank(p.getBasePlugin()) || isAccepted(p.getBasePlugin())); - } - })); - } - - public void doStart(List<JpaPlugin> basePlugins) { - pluginsByKey = Maps.newHashMap(); - ClassLoadersCollection classLoaders = new ClassLoadersCollection(Thread.currentThread().getContextClassLoader()); - - List<JpaPlugin> pluginsMetadata = Lists.newArrayList(basePlugins); - createClassloaders(classLoaders, basePlugins); - pluginsMetadata.addAll(extendClassloaders(classLoaders, pluginsMetadata)); - instantiatePluginEntryPoints(classLoaders, pluginsMetadata); - - classLoaders.done(); - } - - private void instantiatePluginEntryPoints(ClassLoadersCollection classLoaders, List<JpaPlugin> pluginsMetadata) { - for (JpaPlugin pluginMetadata : pluginsMetadata) { - try { - Class claz = classLoaders.get(pluginMetadata.getKey()).loadClass(pluginMetadata.getPluginClass()); - Plugin plugin = (Plugin) claz.newInstance(); - pluginsByKey.put(pluginMetadata.getKey(), plugin); - - } catch (Exception e) { - throw new SonarException("Fail to load plugin " + pluginMetadata.getKey(), e); - } - } - } - - private List<JpaPlugin> extendClassloaders(ClassLoadersCollection classLoaders, List<JpaPlugin> pluginsMetadata) { - List<JpaPlugin> extensions = Lists.newArrayList(); - // Extend plugins by other plugins - for (JpaPlugin pluginMetadata : pluginsMetadata) { - String pluginKey = pluginMetadata.getKey(); - String basePluginKey = pluginMetadata.getBasePlugin(); - if (StringUtils.isNotEmpty(basePluginKey)) { - if (classLoaders.get(basePluginKey) != null) { - LOG.debug("Plugin {} extends {}", pluginKey, basePluginKey); - List<URL> urls = download(pluginMetadata); - classLoaders.extend(basePluginKey, pluginKey, urls); - extensions.add(pluginMetadata); - - } else { - // Ignored, because base plugin doesn't exists - LOG.warn("Plugin {} extends nonexistent plugin {}", pluginKey, basePluginKey); + void doStart(List<ArtifactDownloader.RemotePluginLocation> remoteLocations) { + PluginFileExtractor extractor = new PluginFileExtractor(); + metadataByKey = Maps.newHashMap(); + for (ArtifactDownloader.RemotePluginLocation remoteLocation : remoteLocations) { + if (isAccepted(remoteLocation.getPluginKey())) { + File pluginFile = artifactDownloader.downloadPlugin(remoteLocation); + PluginMetadata metadata = extractor.installInSameLocation(pluginFile, remoteLocation.isCore()); + if (StringUtils.isBlank(metadata.getBasePlugin()) || isAccepted(metadata.getBasePlugin())) { + // TODO log when excluding plugin + metadataByKey.put(metadata.getKey(), metadata); } } } - return extensions; + classLoaders = new PluginClassloaders(Thread.currentThread().getContextClassLoader()); + pluginsByKey = classLoaders.init(metadataByKey.values()); } - private void createClassloaders(ClassLoadersCollection classLoaders, List<JpaPlugin> basePlugins) { - for (JpaPlugin pluginMetadata : basePlugins) { - if (StringUtils.isEmpty(pluginMetadata.getBasePlugin())) { - String key = pluginMetadata.getKey(); - List<URL> urls = download(pluginMetadata); - classLoaders.createClassLoader(key, urls, pluginMetadata.isUseChildFirstClassLoader() == Boolean.TRUE); - } - } - } - - private List<URL> download(JpaPlugin pluginMetadata) { - List<URL> urls = Lists.newArrayList(); - for (JpaPluginFile pluginFile : pluginMetadata.getFiles()) { - File file = artifactDownloader.downloadExtension(pluginFile); - try { - urls.add(file.toURI().toURL()); - - } catch (MalformedURLException e) { - throw new SonarException("Can not get the URL of: " + file, e); - } + public void stop() { + if (classLoaders != null) { + classLoaders.clean(); + classLoaders = null; } - return urls; } public Collection<Plugin> getPlugins() { @@ -175,13 +113,18 @@ public class BatchPluginRepository implements PluginRepository { return new Property[0]; } + public Collection<PluginMetadata> getMetadata() { + return metadataByKey.values(); + } + + public PluginMetadata getMetadata(String pluginKey) { + return metadataByKey.get(pluginKey); + } + boolean isAccepted(String pluginKey) { - if (whiteList!=null) { + if (whiteList != null) { return whiteList.contains(pluginKey); } - if (blackList!=null) { - return !blackList.contains(pluginKey); - } - return true; + return blackList == null || !blackList.contains(pluginKey); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapModule.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapModule.java index fda540156a8..0eaf338f8fa 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapModule.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapModule.java @@ -26,7 +26,6 @@ import org.sonar.api.utils.HttpDownloader; import org.sonar.batch.FakeMavenPluginExecutor; import org.sonar.batch.MavenPluginExecutor; import org.sonar.batch.ServerMetadata; -import org.sonar.core.plugin.JpaPluginDao; import org.sonar.jpa.session.DatabaseSessionProvider; import org.sonar.jpa.session.DriverDatabaseConnector; import org.sonar.jpa.session.ThreadLocalDatabaseSessionFactory; @@ -74,7 +73,6 @@ public class BootstrapModule extends Module { // LIMITATION : list of plugins to download is currently loaded from database. It should be loaded from // remote HTTP index. - addComponent(JpaPluginDao.class); addComponent(BatchPluginRepository.class); addComponent(BatchExtensionInstaller.class); addComponent(ProjectExtensionInstaller.class); diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ArtifactDownloaderTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ArtifactDownloaderTest.java index e318ca69249..92893dfa3f9 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ArtifactDownloaderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ArtifactDownloaderTest.java @@ -22,8 +22,6 @@ package org.sonar.batch.bootstrap; import org.junit.Test; import org.sonar.api.utils.HttpDownloader; import org.sonar.batch.ServerMetadata; -import org.sonar.core.plugin.JpaPlugin; -import org.sonar.core.plugin.JpaPluginFile; import java.io.File; import java.io.IOException; @@ -50,19 +48,19 @@ public class ArtifactDownloaderTest { verify(httpDownloader).download(new URI("http://sonar:8000/deploy/jdbc-driver.jar"), jdbcDriver); } - @Test - public void shouldDownloadExtension() throws IOException, URISyntaxException { - ServerMetadata server = mock(ServerMetadata.class); - when(server.getURL()).thenReturn("http://sonar:8000"); - - HttpDownloader httpDownloader = mock(HttpDownloader.class); - TempDirectories workingDirectories = new TempDirectories(); - - ArtifactDownloader downloader = new ArtifactDownloader(httpDownloader, workingDirectories, server); - JpaPluginFile extension = new JpaPluginFile(new JpaPlugin("findbugs"), "bcel.jar"); - File bcel = downloader.downloadExtension(extension); - - assertNotNull(bcel); - verify(httpDownloader).download(new URI("http://sonar:8000/deploy/plugins/findbugs/bcel.jar"), bcel); - } +// @Test +// public void shouldDownloadExtension() throws IOException, URISyntaxException { +// ServerMetadata server = mock(ServerMetadata.class); +// when(server.getURL()).thenReturn("http://sonar:8000"); +// +// HttpDownloader httpDownloader = mock(HttpDownloader.class); +// TempDirectories workingDirectories = new TempDirectories(); +// +// ArtifactDownloader downloader = new ArtifactDownloader(httpDownloader, workingDirectories, server); +// JpaPluginFile extension = new JpaPluginFile(new JpaPlugin("findbugs"), "bcel.jar"); +// File bcel = downloader.downloadExtension(extension); +// +// assertNotNull(bcel); +// verify(httpDownloader).download(new URI("http://sonar:8000/deploy/plugins/findbugs/bcel.jar"), bcel); +// } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchPluginRepositoryTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchPluginRepositoryTest.java index af8dbec7198..9fc772f0dd5 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchPluginRepositoryTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchPluginRepositoryTest.java @@ -1,112 +1,122 @@ /* - * Sonar, open source software quality management tool. - * Copyright (C) 2008-2011 SonarSource - * mailto:contact AT sonarsource DOT com - * - * Sonar 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. - * - * Sonar 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 Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ +* Sonar, open source software quality management tool. +* Copyright (C) 2008-2011 SonarSource +* mailto:contact AT sonarsource DOT com +* +* Sonar 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. +* +* Sonar 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 Sonar; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 +*/ package org.sonar.batch.bootstrap; -import com.google.common.collect.Lists; import org.apache.commons.configuration.PropertiesConfiguration; -import org.codehaus.plexus.classworlds.realm.ClassRealm; import org.codehaus.plexus.util.FileUtils; -import org.hamcrest.BaseMatcher; -import org.hamcrest.Description; import org.hamcrest.Matchers; +import org.junit.After; import org.junit.Test; import org.sonar.api.CoreProperties; -import org.sonar.api.Plugin; -import org.sonar.core.plugin.JpaPlugin; -import org.sonar.core.plugin.JpaPluginDao; -import org.sonar.core.plugin.JpaPluginFile; +import java.io.File; +import java.io.IOException; import java.util.Arrays; -import java.util.List; -import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.not; -import static org.hamcrest.core.Is.is; import static org.hamcrest.core.IsNull.nullValue; import static org.junit.Assert.assertThat; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.argThat; +import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class BatchPluginRepositoryTest { + private BatchPluginRepository repository; + + @After + public void tearDown() { + if (repository!=null) { + repository.stop(); + } + } + @Test - public void shouldLoadPlugin() { - ArtifactDownloader extensionDownloader = mock(ArtifactDownloader.class); - when(extensionDownloader.downloadExtension(any(JpaPluginFile.class))).thenReturn( - FileUtils.toFile(getClass().getResource("/org/sonar/batch/bootstrap/BatchPluginRepositoryTest/sonar-artifact-size-plugin-0.2.jar"))); - BatchPluginRepository repository = new BatchPluginRepository(null, extensionDownloader, new PropertiesConfiguration()); - - JpaPlugin plugin = new JpaPlugin("artifactsize"); - plugin.setPluginClass("org.sonar.plugins.artifactsize.ArtifactSizePlugin"); - plugin.createFile("sonar-artifact-size-plugin-0.2.jar"); - repository.doStart(Arrays.asList(plugin)); - - Plugin entryPoint = repository.getPlugin("artifactsize"); - assertThat(entryPoint, not(nullValue())); - ClassRealm classloader = (ClassRealm) entryPoint.getClass().getClassLoader(); - assertThat(classloader.getId(), is("artifactsize")); + public void shouldLoadPlugin() throws IOException { + ArtifactDownloader.RemotePluginLocation checkstyleLocation = ArtifactDownloader.RemotePluginLocation.create("checkstyle"); + + ArtifactDownloader downloader = mock(ArtifactDownloader.class); + when(downloader.downloadPlugin(eq(checkstyleLocation))).thenReturn(copyFile("sonar-checkstyle-plugin-2.8.jar")); + + repository = new BatchPluginRepository(downloader, new PropertiesConfiguration()); + + repository.doStart(Arrays.asList(checkstyleLocation)); + + assertThat(repository.getPlugins().size(), Matchers.is(1)); + assertThat(repository.getPlugin("checkstyle"), not(nullValue())); + assertThat(repository.getMetadata().size(), Matchers.is(1)); + assertThat(repository.getMetadata("checkstyle").getName(), Matchers.is("Checkstyle")); } - /** - * Of course clirr does not extend artifact-size plugin in real life ! - */ @Test - public void shouldPluginExtensionInTheSameClassloader() { - ArtifactDownloader extensionDownloader = mock(ArtifactDownloader.class); - prepareDownloader(extensionDownloader, "artifactsize", "/org/sonar/batch/bootstrap/BatchPluginRepositoryTest/sonar-artifact-size-plugin-0.2.jar"); - prepareDownloader(extensionDownloader, "clirr", "/org/sonar/batch/bootstrap/BatchPluginRepositoryTest/sonar-clirr-plugin-1.1.jar"); - BatchPluginRepository repository = new BatchPluginRepository(null, extensionDownloader, new PropertiesConfiguration()); - - JpaPlugin pluginBase = new JpaPlugin("artifactsize"); - pluginBase.setPluginClass("org.sonar.plugins.artifactsize.ArtifactSizePlugin"); - pluginBase.createFile("sonar-artifact-size-plugin-0.2.jar"); - - JpaPlugin pluginExtension = new JpaPlugin("clirr"); - pluginExtension.setBasePlugin("artifactsize"); - pluginExtension.setPluginClass("org.sonar.plugins.clirr.ClirrPlugin"); - pluginExtension.createFile("sonar-clirr-plugin-1.1.jar"); - - repository.doStart(Arrays.asList(pluginBase, pluginExtension)); - - Plugin entryPointBase = repository.getPlugin("artifactsize"); - Plugin entryPointExtension = repository.getPlugin("clirr"); - assertThat(entryPointBase.getClass().getClassLoader(), is(entryPointExtension.getClass().getClassLoader())); + public void shouldLoadPluginExtension() throws IOException { + ArtifactDownloader.RemotePluginLocation checkstyleLocation = ArtifactDownloader.RemotePluginLocation.create("checkstyle"); + ArtifactDownloader.RemotePluginLocation checkstyleExtLocation = ArtifactDownloader.RemotePluginLocation.create("checkstyleextensions"); + + ArtifactDownloader downloader = mock(ArtifactDownloader.class); + when(downloader.downloadPlugin(eq(checkstyleLocation))).thenReturn(copyFile("sonar-checkstyle-plugin-2.8.jar")); + when(downloader.downloadPlugin(eq(checkstyleExtLocation))).thenReturn(copyFile("sonar-checkstyle-extensions-plugin-0.1-SNAPSHOT.jar")); + + repository = new BatchPluginRepository(downloader, new PropertiesConfiguration()); + + repository.doStart(Arrays.asList(checkstyleLocation, checkstyleExtLocation)); + + assertThat(repository.getPlugins().size(), Matchers.is(2)); + assertThat(repository.getPlugin("checkstyle"), not(nullValue())); + assertThat(repository.getPlugin("checkstyleextensions"), not(nullValue())); + assertThat(repository.getMetadata().size(), Matchers.is(2)); + assertThat(repository.getMetadata("checkstyle").getName(), Matchers.is("Checkstyle")); + assertThat(repository.getMetadata("checkstyleextensions").getVersion(), Matchers.is("0.1-SNAPSHOT")); } - private void prepareDownloader(ArtifactDownloader extensionDownloader, final String pluginKey, final String filename) { - when(extensionDownloader.downloadExtension(argThat(new BaseMatcher<JpaPluginFile>() { - public boolean matches(Object o) { - return o != null && ((JpaPluginFile) o).getPluginKey().equals(pluginKey); - } + @Test + public void shouldExcludePluginAndItsExtensions() throws IOException { + ArtifactDownloader.RemotePluginLocation checkstyleLocation = ArtifactDownloader.RemotePluginLocation.create("checkstyle"); + ArtifactDownloader.RemotePluginLocation checkstyleExtLocation = ArtifactDownloader.RemotePluginLocation.create("checkstyleextensions"); - public void describeTo(Description description) { + ArtifactDownloader downloader = mock(ArtifactDownloader.class); + when(downloader.downloadPlugin(eq(checkstyleLocation))).thenReturn(copyFile("sonar-checkstyle-plugin-2.8.jar")); + when(downloader.downloadPlugin(eq(checkstyleExtLocation))).thenReturn(copyFile("sonar-checkstyle-extensions-plugin-0.1-SNAPSHOT.jar")); - } - }))).thenReturn(FileUtils.toFile(getClass().getResource(filename))); + PropertiesConfiguration conf = new PropertiesConfiguration(); + conf.setProperty(CoreProperties.EXCLUDE_PLUGINS, "checkstyle"); + repository = new BatchPluginRepository(downloader, conf); + + repository.doStart(Arrays.asList(checkstyleLocation, checkstyleExtLocation)); + + assertThat(repository.getPlugins().size(), Matchers.is(0)); + assertThat(repository.getMetadata().size(), Matchers.is(0)); } + private File copyFile(String filename) throws IOException { + File file = FileUtils.toFile(getClass().getResource("/org/sonar/batch/bootstrap/BatchPluginRepositoryTest/" + filename)); + File tempDir = new File("target/test-tmp/BatchPluginRepositoryTest"); + FileUtils.forceMkdir(tempDir); + FileUtils.copyFileToDirectory(file, tempDir); + return new File(tempDir, filename); + } + + @Test public void shouldAlwaysAcceptIfNoWhiteListAndBlackList() { - BatchPluginRepository repository = new BatchPluginRepository(mock(JpaPluginDao.class), mock(ArtifactDownloader.class), new PropertiesConfiguration()); + repository = new BatchPluginRepository(mock(ArtifactDownloader.class), new PropertiesConfiguration()); assertThat(repository.isAccepted("pmd"), Matchers.is(true)); } @@ -115,7 +125,7 @@ public class BatchPluginRepositoryTest { PropertiesConfiguration conf = new PropertiesConfiguration(); conf.setProperty(CoreProperties.INCLUDE_PLUGINS, "checkstyle,pmd,findbugs"); conf.setProperty(CoreProperties.EXCLUDE_PLUGINS, "cobertura,pmd"); - BatchPluginRepository repository = new BatchPluginRepository(mock(JpaPluginDao.class), mock(ArtifactDownloader.class), conf); + repository = new BatchPluginRepository(mock(ArtifactDownloader.class), conf); assertThat(repository.isAccepted("pmd"), Matchers.is(true)); } @@ -124,7 +134,7 @@ public class BatchPluginRepositoryTest { public void shouldCheckWhitelist() { PropertiesConfiguration conf = new PropertiesConfiguration(); conf.setProperty(CoreProperties.INCLUDE_PLUGINS, "checkstyle,pmd,findbugs"); - BatchPluginRepository repository = new BatchPluginRepository(mock(JpaPluginDao.class), mock(ArtifactDownloader.class), conf); + repository = new BatchPluginRepository(mock(ArtifactDownloader.class), conf); assertThat(repository.isAccepted("checkstyle"), Matchers.is(true)); assertThat(repository.isAccepted("pmd"), Matchers.is(true)); @@ -135,26 +145,11 @@ public class BatchPluginRepositoryTest { public void shouldCheckBlackListIfNoWhiteList() { PropertiesConfiguration conf = new PropertiesConfiguration(); conf.setProperty(CoreProperties.EXCLUDE_PLUGINS, "checkstyle,pmd,findbugs"); - BatchPluginRepository repository = new BatchPluginRepository(mock(JpaPluginDao.class), mock(ArtifactDownloader.class), conf); + repository = new BatchPluginRepository(mock(ArtifactDownloader.class), conf); assertThat(repository.isAccepted("checkstyle"), Matchers.is(false)); assertThat(repository.isAccepted("pmd"), Matchers.is(false)); assertThat(repository.isAccepted("cobertura"), Matchers.is(true)); } - @Test - public void shouldExcludePluginDependents() { - JpaPlugin pmd = new JpaPlugin("pmd"); - JpaPlugin checkstyle = new JpaPlugin("checkstyle"); - JpaPlugin checkstyleExtension = new JpaPlugin("checkstyle-ext"); - checkstyleExtension.setBasePlugin("checkstyle"); - - PropertiesConfiguration conf = new PropertiesConfiguration(); - conf.setProperty(CoreProperties.EXCLUDE_PLUGINS, "checkstyle"); - BatchPluginRepository repository = new BatchPluginRepository(mock(JpaPluginDao.class), mock(ArtifactDownloader.class), conf); - - List<JpaPlugin> filteredPlugins = repository.filter(Arrays.asList(checkstyle, checkstyleExtension, pmd)); - assertThat(filteredPlugins.size(), Matchers.is(1)); - assertThat(filteredPlugins, hasItem(pmd)); - } } diff --git a/sonar-batch/src/test/resources/org/sonar/batch/bootstrap/BatchPluginRepositoryTest/sonar-artifact-size-plugin-0.2.jar b/sonar-batch/src/test/resources/org/sonar/batch/bootstrap/BatchPluginRepositoryTest/sonar-artifact-size-plugin-0.2.jar Binary files differdeleted file mode 100644 index 917d9860f5b..00000000000 --- a/sonar-batch/src/test/resources/org/sonar/batch/bootstrap/BatchPluginRepositoryTest/sonar-artifact-size-plugin-0.2.jar +++ /dev/null diff --git a/sonar-batch/src/test/resources/org/sonar/batch/bootstrap/BatchPluginRepositoryTest/sonar-checkstyle-extensions-plugin-0.1-SNAPSHOT.jar b/sonar-batch/src/test/resources/org/sonar/batch/bootstrap/BatchPluginRepositoryTest/sonar-checkstyle-extensions-plugin-0.1-SNAPSHOT.jar Binary files differnew file mode 100644 index 00000000000..4ae5393cee5 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/bootstrap/BatchPluginRepositoryTest/sonar-checkstyle-extensions-plugin-0.1-SNAPSHOT.jar diff --git a/sonar-batch/src/test/resources/org/sonar/batch/bootstrap/BatchPluginRepositoryTest/sonar-checkstyle-plugin-2.8.jar b/sonar-batch/src/test/resources/org/sonar/batch/bootstrap/BatchPluginRepositoryTest/sonar-checkstyle-plugin-2.8.jar Binary files differnew file mode 100644 index 00000000000..f937399bec5 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/bootstrap/BatchPluginRepositoryTest/sonar-checkstyle-plugin-2.8.jar diff --git a/sonar-batch/src/test/resources/org/sonar/batch/bootstrap/BatchPluginRepositoryTest/sonar-clirr-plugin-1.1.jar b/sonar-batch/src/test/resources/org/sonar/batch/bootstrap/BatchPluginRepositoryTest/sonar-clirr-plugin-1.1.jar Binary files differdeleted file mode 100644 index ef2ee8c4ac4..00000000000 --- a/sonar-batch/src/test/resources/org/sonar/batch/bootstrap/BatchPluginRepositoryTest/sonar-clirr-plugin-1.1.jar +++ /dev/null |