diff options
Diffstat (limited to 'sonar-batch')
11 files changed, 156 insertions, 529 deletions
diff --git a/sonar-batch/pom.xml b/sonar-batch/pom.xml index 8fcf5b43847..9e95782e6d3 100644 --- a/sonar-batch/pom.xml +++ b/sonar-batch/pom.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.codehaus.sonar</groupId> @@ -9,7 +10,6 @@ <groupId>org.codehaus.sonar</groupId> <artifactId>sonar-batch</artifactId> - <packaging>jar</packaging> <name>Sonar :: Batch</name> <dependencies> @@ -23,6 +23,10 @@ </dependency> <dependency> <groupId>org.codehaus.sonar</groupId> + <artifactId>sonar-home</artifactId> + </dependency> + <dependency> + <groupId>org.codehaus.sonar</groupId> <artifactId>sonar-java-api</artifactId> </dependency> <dependency> diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchSonarCache.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchSonarCache.java deleted file mode 100644 index d656c21c447..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchSonarCache.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2008-2012 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 org.apache.commons.lang.StringUtils; -import org.sonar.api.CoreProperties; -import org.sonar.api.config.Settings; -import org.sonar.api.task.TaskExtension; -import org.sonar.batch.cache.SonarCache; - -import java.io.File; - -public class BatchSonarCache implements TaskExtension { - - private Settings settings; - private SonarCache cache; - - public BatchSonarCache(Settings settings) { - this.settings = settings; - } - - public void start() { - // Try to get Sonar user home from property - String sonarUserHome = settings.getString(CoreProperties.SONAR_USER_HOME_PROPERTY); - if (StringUtils.isBlank(sonarUserHome)) { - // Try to get Sonar user home from environment variable - sonarUserHome = settings.getString(CoreProperties.SONAR_USER_HOME); - } - if (StringUtils.isBlank(sonarUserHome)) { - // Default - sonarUserHome = System.getProperty("user.home") + File.separator + ".sonar"; - } - - SonarCache.Builder builder = SonarCache.create(new File(sonarUserHome)); - this.cache = builder.build(); - } - - public SonarCache getCache() { - return cache; - } -} 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 39614208ea1..9e4d54b201f 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 @@ -74,7 +74,7 @@ public class BootstrapModule extends Module { container.addSingleton(HttpDownloader.class); container.addSingleton(UriReader.class); container.addSingleton(PluginDownloader.class); - container.addSingleton(BatchSonarCache.class); + container.addPicoAdapter(new FileCacheProvider()); for (Object component : boostrapperComponents) { if (component != null) { container.addSingleton(component); diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/FileCacheProvider.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/FileCacheProvider.java new file mode 100644 index 00000000000..610083d98cd --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/FileCacheProvider.java @@ -0,0 +1,38 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2012 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 org.picocontainer.injectors.ProviderAdapter; +import org.sonar.api.config.Settings; +import org.sonar.home.cache.FileCache; +import org.sonar.home.cache.FileCacheBuilder; +import org.sonar.home.log.Slf4jLog; + +public class FileCacheProvider extends ProviderAdapter { + private FileCache cache; + + public FileCache provide(Settings settings) { + if (cache == null) { + String home = settings.getString("sonar.userHome"); + cache = new FileCacheBuilder().setLog(new Slf4jLog(FileCache.class)).setUserHome(home).build(); + } + return cache; + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/JdbcDriverHolder.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/JdbcDriverHolder.java index 06b36e2b9c6..4db53d7db31 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/JdbcDriverHolder.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/JdbcDriverHolder.java @@ -25,7 +25,7 @@ import org.slf4j.LoggerFactory; import org.sonar.api.CoreProperties; import org.sonar.api.config.Settings; import org.sonar.api.utils.SonarException; -import org.sonar.batch.cache.SonarCache; +import org.sonar.home.cache.FileCache; import java.io.File; import java.io.IOException; @@ -44,43 +44,38 @@ public class JdbcDriverHolder { private ServerClient serverClient; private Settings settings; - private BatchSonarCache batchCache; + private FileCache fileCache; // initialized in start() private JdbcDriverClassLoader classLoader = null; - public JdbcDriverHolder(BatchSonarCache batchCache, Settings settings, ServerClient serverClient) { + public JdbcDriverHolder(FileCache fileCache, Settings settings, ServerClient serverClient) { this.serverClient = serverClient; this.settings = settings; - this.batchCache = batchCache; + this.fileCache = fileCache; } public void start() { if (!settings.getBoolean(CoreProperties.DRY_RUN)) { try { LOG.info("Install JDBC driver"); - String[] nameAndMd5 = downloadJdbcDriverIndex(); - String filename = nameAndMd5[0]; - String remoteMd5 = nameAndMd5[1]; - File driverInCache = getSonarCache().getFileFromCache(filename, remoteMd5); - if (driverInCache == null) { - File tmpDownloadFile = getSonarCache().getTemporaryFile(); - String url = "/deploy/" + filename; - if (LOG.isDebugEnabled()) { - LOG.debug("Downloading {} to {}", url, tmpDownloadFile.getAbsolutePath()); + String[] nameAndHash = downloadJdbcDriverIndex(); + String filename = nameAndHash[0]; + String hash = nameAndHash[1]; + + File jdbcDriver = fileCache.get(filename, hash, new FileCache.Downloader() { + public void download(String filename, File toFile) throws IOException { + String url = "/deploy/" + filename; + if (LOG.isDebugEnabled()) { + LOG.debug("Download {} to {}", url, toFile.getAbsolutePath()); + } else { + LOG.info("Download {}", filename); + } + serverClient.download(url, toFile); } - else { - LOG.info("Downloading {}", filename); - } - serverClient.download(url, tmpDownloadFile); - String md5 = getSonarCache().cacheFile(tmpDownloadFile, filename); - driverInCache = getSonarCache().getFileFromCache(filename, md5); - if (!md5.equals(remoteMd5)) { - throw new SonarException("INVALID CHECKSUM: File " + driverInCache.getAbsolutePath() + " was expected to have checksum " + remoteMd5 - + " but was downloaded with checksum " + md5); - } - } - classLoader = initClassloader(driverInCache); + }); + + classLoader = initClassloader(jdbcDriver); } catch (SonarException e) { throw e; } catch (Exception e) { @@ -89,10 +84,6 @@ public class JdbcDriverHolder { } } - private SonarCache getSonarCache() { - return batchCache.getCache(); - } - @VisibleForTesting JdbcDriverClassLoader getClassLoader() { return classLoader; @@ -148,7 +139,7 @@ public class JdbcDriverHolder { private String[] downloadJdbcDriverIndex() { String url = "/deploy/jdbc-driver.txt"; try { - LOG.debug("Downloading index of jdbc-driver"); + LOG.debug("Download index of jdbc-driver"); String indexContent = serverClient.request(url); return indexContent.split("\\|"); } catch (Exception e) { @@ -159,7 +150,7 @@ public class JdbcDriverHolder { static class JdbcDriverClassLoader extends URLClassLoader { public JdbcDriverClassLoader(URL jdbcDriver, ClassLoader parent) { - super(new URL[] {jdbcDriver}, parent); + super(new URL[]{jdbcDriver}, parent); } public void clearReferencesJdbc() { diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/PluginDownloader.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/PluginDownloader.java index dadabefd1d8..f037413a278 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/PluginDownloader.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/PluginDownloader.java @@ -26,11 +26,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.BatchComponent; import org.sonar.api.utils.SonarException; -import org.sonar.batch.cache.SonarCache; import org.sonar.core.plugins.RemotePlugin; import org.sonar.core.plugins.RemotePluginFile; +import org.sonar.home.cache.FileCache; import java.io.File; +import java.io.IOException; import java.util.List; public class PluginDownloader implements BatchComponent { @@ -38,45 +39,32 @@ public class PluginDownloader implements BatchComponent { private static final Logger LOG = LoggerFactory.getLogger(PluginDownloader.class); private ServerClient server; - private BatchSonarCache batchCache; + private FileCache fileCache; - public PluginDownloader(BatchSonarCache batchCache, ServerClient server) { + public PluginDownloader(FileCache fileCache, ServerClient server) { this.server = server; - this.batchCache = batchCache; + this.fileCache = fileCache; } - private SonarCache getSonarCache() { - return batchCache.getCache(); - } - - public List<File> downloadPlugin(RemotePlugin remote) { + public List<File> downloadPlugin(final RemotePlugin remote) { try { List<File> files = Lists.newArrayList(); - for (RemotePluginFile file : remote.getFiles()) { - File fileInCache = getSonarCache().getFileFromCache(file.getFilename(), file.getMd5()); - if (fileInCache == null) { - File tmpDownloadFile = getSonarCache().getTemporaryFile(); - String url = "/deploy/plugins/" + remote.getKey() + "/" + file.getFilename(); - if (LOG.isDebugEnabled()) { - LOG.debug("Downloading {} to {}", url, tmpDownloadFile.getAbsolutePath()); - } - else { - LOG.info("Downloading {}", file.getFilename()); - } - server.download(url, tmpDownloadFile); - String md5 = getSonarCache().cacheFile(tmpDownloadFile, file.getFilename()); - fileInCache = getSonarCache().getFileFromCache(file.getFilename(), md5); - if (!md5.equals(file.getMd5())) { - throw new SonarException("INVALID CHECKSUM: File " + fileInCache.getAbsolutePath() + " was expected to have checksum " + file.getMd5() - + " but was downloaded with checksum " + md5); + for (final RemotePluginFile file : remote.getFiles()) { + File cachedFile = fileCache.get(file.getFilename(), file.getHash(), new FileCache.Downloader() { + public void download(String filename, File toFile) throws IOException { + String url = "/deploy/plugins/" + remote.getKey() + "/" + file.getFilename(); + if (LOG.isDebugEnabled()) { + LOG.debug("Download {} to {}", url, toFile.getAbsolutePath()); + } else { + LOG.info("Download {}", file.getFilename()); + } + server.download(url, toFile); } - } - files.add(fileInCache); + }); + files.add(cachedFile); } return files; - } catch (SonarException e) { - throw e; } catch (Exception e) { throw new SonarException("Fail to download plugin: " + remote.getKey(), e); } @@ -85,7 +73,7 @@ public class PluginDownloader implements BatchComponent { public List<RemotePlugin> downloadPluginIndex() { String url = "/deploy/plugins/index.txt"; try { - LOG.debug("Downloading index of plugins"); + LOG.debug("Download index of plugins"); String indexContent = server.request(url); String[] rows = StringUtils.split(indexContent, CharUtils.LF); List<RemotePlugin> remoteLocations = Lists.newArrayList(); diff --git a/sonar-batch/src/main/java/org/sonar/batch/cache/SonarCache.java b/sonar-batch/src/main/java/org/sonar/batch/cache/SonarCache.java deleted file mode 100644 index 77499426727..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/cache/SonarCache.java +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2008-2012 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.cache; - -import com.google.common.io.Closeables; -import com.google.common.io.Files; -import org.apache.commons.codec.digest.DigestUtils; -import org.apache.commons.io.FileUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.sonar.api.utils.SonarException; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; - -/** - * This class is responsible for managing Sonar batch file cache. You can put file into cache and - * later try to retrieve them. MD5 is used to differentiate files (name is not secure as files may come - * from different Sonar servers and have same name but be actually different, and same for SNAPSHOTs). - * Default location of cache is - * @author Julien HENRY - * - */ -public class SonarCache { - - private static final Logger LOG = LoggerFactory.getLogger(SonarCache.class); - - private static final int TEMP_FILE_ATTEMPTS = 10000; - - private File cacheLocation; - /** - * Temporary directory where files should be stored before be inserted in the cache. - * Having a temporary close to the final location (read on same FS) will assure - * the move will be atomic. - */ - private File tmpDir; - - private SonarCache(File cacheLocation) { - this.cacheLocation = cacheLocation; - tmpDir = new File(cacheLocation, "tmp"); - if (!cacheLocation.exists()) { - LOG.debug("Creating cache directory: {}", cacheLocation.getAbsolutePath()); - try { - FileUtils.forceMkdir(cacheLocation); - } catch (IOException e) { - throw new RuntimeException("Unable to create cache directory " + cacheLocation.getAbsolutePath(), e); - } - } - } - - public static class Builder { - - private File sonarUserHomeLocation; - private File cacheLocation; - - public Builder(File sonarUserHomeLocation) { - this.sonarUserHomeLocation = sonarUserHomeLocation; - } - - public Builder setCacheLocation(File cacheLocation) { - this.cacheLocation = cacheLocation; - return this; - } - - public SonarCache build() { - if (cacheLocation == null) { - return new SonarCache(new File(sonarUserHomeLocation, "cache")); - } - else { - return new SonarCache(cacheLocation); - } - } - - } - - public static Builder create(File sonarUserHomeLocation) { - if (sonarUserHomeLocation == null) { - throw new SonarException("Sonar user home directory should not be null"); - } - return new Builder(sonarUserHomeLocation); - } - - /** - * Move the given file inside the cache. Return the MD5 of the cached file. - * @param sourceFile - * @throws IOException - */ - public String cacheFile(File sourceFile, String filename) throws IOException { - LOG.debug("Trying to cache file {} with filename {}", sourceFile.getAbsolutePath(), filename); - File tmpFileName = null; - try { - if (!sourceFile.getParentFile().equals(getTmpDir())) { - // Provided file is not close to the cache so we will move it first in a temporary file (could be non atomic) - tmpFileName = getTemporaryFile(); - Files.move(sourceFile, tmpFileName); - } - else { - tmpFileName = sourceFile; - } - // Now compute the md5 to find the final destination - String md5; - FileInputStream fis = null; - try { - fis = new FileInputStream(tmpFileName); - md5 = DigestUtils.md5Hex(fis); - } finally { - Closeables.closeQuietly(fis); - } - File finalDir = new File(cacheLocation, md5); - File finalFileName = new File(finalDir, filename); - // Try to create final destination folder - FileUtils.forceMkdir(finalDir); - // Now try to move the file from temporary folder to final location - boolean rename = tmpFileName.renameTo(finalFileName); - if (!rename) { - // Check if the file was already in cache - if (!finalFileName.exists()) { - LOG.warn("Unable to rename {} to {}", tmpFileName.getAbsolutePath(), finalFileName.getAbsolutePath()); - LOG.warn("A copy/delete will be tempted but with no garantee of atomicity"); - FileUtils.moveFile(tmpFileName, finalFileName); - } - } - LOG.debug("File cached at {}", finalFileName.getAbsolutePath()); - return md5; - } finally { - FileUtils.deleteQuietly(tmpFileName); - } - - } - - /** - * Look for a file in the cache by its filename and md5 checksum. If the file is not - * present then return null. - */ - public File getFileFromCache(String filename, String md5) { - File location = new File(new File(cacheLocation, md5), filename); - LOG.debug("Looking for {}", location.getAbsolutePath()); - if (location.exists()) { - return location; - } - LOG.debug("No file found in the cache with name {} and checksum {}", filename, md5); - return null; - } - - /** - * Return a temporary file that caller can use to store file content before - * asking for caching it with {@link #cacheFile(File)}. - * This is to avoid extra copy. - * @return - * @throws IOException - */ - public File getTemporaryFile() throws IOException { - return createTempFile(getTmpDir()); - } - - /** - * Create a temporary file in the given directory. - * @param baseDir - * @return - * @throws IOException - */ - private static File createTempFile(File baseDir) throws IOException { - String baseName = System.currentTimeMillis() + "-"; - - for (int counter = 0; counter < TEMP_FILE_ATTEMPTS; counter++) { - File tempFile = new File(baseDir, baseName + counter); - if (tempFile.createNewFile()) { - return tempFile; - } - } - throw new IOException("Failed to create temporary file in " + baseDir.getAbsolutePath() + " within " - + TEMP_FILE_ATTEMPTS + " attempts (tried " - + baseName + "0 to " + baseName + (TEMP_FILE_ATTEMPTS - 1) + ')'); - } - - public File getTmpDir() { - if (!tmpDir.exists()) { - LOG.debug("Creating temporary cache directory: {}", tmpDir.getAbsolutePath()); - try { - FileUtils.forceMkdir(tmpDir); - } catch (IOException e) { - throw new RuntimeException("Unable to create temporary cache directory " + tmpDir.getAbsolutePath(), e); - } - } - return tmpDir; - } - - public File getCacheLocation() { - return cacheLocation; - } -} diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/FileCacheProviderTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/FileCacheProviderTest.java new file mode 100644 index 00000000000..305e6c9c146 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/FileCacheProviderTest.java @@ -0,0 +1,47 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2012 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 org.junit.Test; +import org.sonar.api.config.Settings; +import org.sonar.home.cache.FileCache; + +import static org.fest.assertions.Assertions.assertThat; + +public class FileCacheProviderTest { + @Test + public void provide() { + FileCacheProvider provider = new FileCacheProvider(); + FileCache cache = provider.provide(new Settings()); + + assertThat(cache).isNotNull(); + assertThat(cache.getDir()).isNotNull().exists(); + } + + @Test + public void keep_singleton_instance() { + FileCacheProvider provider = new FileCacheProvider(); + Settings settings = new Settings(); + FileCache cache1 = provider.provide(settings); + FileCache cache2 = provider.provide(settings); + + assertThat(cache1).isSameAs(cache2); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/JdbcDriverHolderTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/JdbcDriverHolderTest.java index 0047141fb2d..df091fab76b 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/JdbcDriverHolderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/JdbcDriverHolderTest.java @@ -25,15 +25,15 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; -import org.mockito.Mockito; import org.sonar.api.CoreProperties; import org.sonar.api.config.Settings; -import org.sonar.api.utils.SonarException; -import org.sonar.batch.cache.SonarCache; +import org.sonar.home.cache.FileCache; import java.io.File; import static org.fest.assertions.Assertions.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; @@ -60,15 +60,10 @@ public class JdbcDriverHolderTest { @Test public void should_extend_classloader_with_jdbc_driver() throws Exception { - SonarCache cache = mock(SonarCache.class); - BatchSonarCache batchCache = mock(BatchSonarCache.class); - when(batchCache.getCache()).thenReturn(cache); + FileCache cache = mock(FileCache.class); File fakeDriver = new File(getClass().getResource("/org/sonar/batch/bootstrap/JdbcDriverHolderTest/jdbc-driver.jar").toURI()); - when(cache.cacheFile(Mockito.any(File.class), Mockito.anyString())).thenReturn("fakemd5"); - when(cache.getFileFromCache(Mockito.anyString(), Mockito.anyString())) - .thenReturn(null) - .thenReturn(fakeDriver); + when(cache.get(eq("ojdbc14.jar"), eq("fakemd5"), any(FileCache.Downloader.class))).thenReturn(fakeDriver); /* jdbc-driver.jar has just one file /foo/foo.txt */ assertThat(Thread.currentThread().getContextClassLoader().getResource("foo/foo.txt")).isNull(); @@ -77,7 +72,7 @@ public class JdbcDriverHolderTest { when(server.request("/deploy/jdbc-driver.txt")).thenReturn("ojdbc14.jar|fakemd5"); when(server.request("/deploy/ojdbc14.jar")).thenReturn("fakecontent"); - JdbcDriverHolder holder = new JdbcDriverHolder(batchCache, new Settings(), server); + JdbcDriverHolder holder = new JdbcDriverHolder(cache, new Settings(), server); holder.start(); assertThat(holder.getClassLoader().getResource("foo/foo.txt")).isNotNull(); @@ -90,34 +85,11 @@ public class JdbcDriverHolderTest { } @Test - public void should_fail_if_checksum_mismatch() throws Exception { - SonarCache cache = mock(SonarCache.class); - BatchSonarCache batchCache = mock(BatchSonarCache.class); - when(batchCache.getCache()).thenReturn(cache); - - File fakeDriver = new File(getClass().getResource("/org/sonar/batch/bootstrap/JdbcDriverHolderTest/jdbc-driver.jar").toURI()); - when(cache.cacheFile(Mockito.any(File.class), Mockito.anyString())).thenReturn("anotherfakemd5"); - when(cache.getFileFromCache(Mockito.anyString(), Mockito.anyString())) - .thenReturn(null) - .thenReturn(fakeDriver); - - ServerClient server = mock(ServerClient.class); - when(server.request("/deploy/jdbc-driver.txt")).thenReturn("ojdbc14.jar|fakemd5"); - when(server.request("/deploy/ojdbc14.jar")).thenReturn("fakecontent"); - - JdbcDriverHolder holder = new JdbcDriverHolder(batchCache, new Settings(), server); - - thrown.expect(SonarException.class); - thrown.expectMessage("INVALID CHECKSUM"); - - holder.start(); - } - - @Test public void should_be_disabled_if_dry_run() { + FileCache cache = mock(FileCache.class); Settings settings = new Settings().setProperty(CoreProperties.DRY_RUN, true); ServerClient server = mock(ServerClient.class); - JdbcDriverHolder holder = new JdbcDriverHolder(new BatchSonarCache(new Settings()), settings, server); + JdbcDriverHolder holder = new JdbcDriverHolder(cache, settings, server); holder.start(); diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/PluginDownloaderTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/PluginDownloaderTest.java index 86fca9177d4..d1b21b0fde9 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/PluginDownloaderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/PluginDownloaderTest.java @@ -23,20 +23,18 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; -import org.mockito.Mockito; -import org.sonar.api.config.Settings; import org.sonar.api.utils.SonarException; -import org.sonar.batch.cache.SonarCache; import org.sonar.core.plugins.RemotePlugin; +import org.sonar.home.cache.FileCache; import java.io.File; import java.util.List; import static org.fest.assertions.Assertions.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; public class PluginDownloaderTest { @@ -49,9 +47,10 @@ public class PluginDownloaderTest { @Test public void should_request_list_of_plugins() { + FileCache cache = mock(FileCache.class); ServerClient server = mock(ServerClient.class); when(server.request("/deploy/plugins/index.txt")).thenReturn("checkstyle,true\nsqale,false"); - PluginDownloader downloader = new PluginDownloader(new BatchSonarCache(new Settings()), server); + PluginDownloader downloader = new PluginDownloader(cache, server); List<RemotePlugin> plugins = downloader.downloadPluginIndex(); assertThat(plugins).hasSize(2); @@ -62,52 +61,23 @@ public class PluginDownloaderTest { } @Test - public void should_download_plugin_if_not_cached() throws Exception { - SonarCache cache = mock(SonarCache.class); - BatchSonarCache batchCache = mock(BatchSonarCache.class); - when(batchCache.getCache()).thenReturn(cache); - - File fileInCache = temp.newFile(); - when(cache.cacheFile(Mockito.any(File.class), Mockito.anyString())).thenReturn("fakemd51").thenReturn("fakemd52"); - when(cache.getFileFromCache(Mockito.anyString(), Mockito.anyString())) - .thenReturn(null) - .thenReturn(fileInCache) - .thenReturn(null) - .thenReturn(fileInCache); - ServerClient server = mock(ServerClient.class); - PluginDownloader downloader = new PluginDownloader(batchCache, server); - - RemotePlugin plugin = new RemotePlugin("checkstyle", true) - .addFile("checkstyle-plugin.jar", "fakemd51") - .addFile("checkstyle-extensions.jar", "fakemd52"); - List<File> files = downloader.downloadPlugin(plugin); + public void should_download_plugin() throws Exception { + FileCache cache = mock(FileCache.class); - assertThat(files).hasSize(2); - verify(server).download(Mockito.eq("/deploy/plugins/checkstyle/checkstyle-plugin.jar"), Mockito.any(File.class)); - verify(server).download(Mockito.eq("/deploy/plugins/checkstyle/checkstyle-extensions.jar"), Mockito.any(File.class)); - } + File pluginJar = temp.newFile(); + File extensionJar = temp.newFile(); + when(cache.get(eq("checkstyle-plugin.jar"), eq("fakemd5_1"), any(FileCache.Downloader.class))).thenReturn(pluginJar); + when(cache.get(eq("checkstyle-extensions.jar"), eq("fakemd5_2"), any(FileCache.Downloader.class))).thenReturn(extensionJar); - @Test - public void should_not_download_plugin_if_cached() throws Exception { - SonarCache cache = mock(SonarCache.class); - BatchSonarCache batchCache = mock(BatchSonarCache.class); - when(batchCache.getCache()).thenReturn(cache); - - File fileInCache = temp.newFile(); - when(cache.getFileFromCache(Mockito.anyString(), Mockito.anyString())) - .thenReturn(fileInCache) - .thenReturn(fileInCache); ServerClient server = mock(ServerClient.class); - PluginDownloader downloader = new PluginDownloader(batchCache, server); + PluginDownloader downloader = new PluginDownloader(cache, server); RemotePlugin plugin = new RemotePlugin("checkstyle", true) - .addFile("checkstyle-plugin.jar", "fakemd51") - .addFile("checkstyle-extensions.jar", "fakemd52"); + .addFile("checkstyle-plugin.jar", "fakemd5_1") + .addFile("checkstyle-extensions.jar", "fakemd5_2"); List<File> files = downloader.downloadPlugin(plugin); assertThat(files).hasSize(2); - verify(server, never()).download(Mockito.anyString(), Mockito.any(File.class)); - verify(cache, never()).cacheFile(Mockito.any(File.class), Mockito.anyString()); } @Test @@ -117,28 +87,6 @@ public class PluginDownloaderTest { ServerClient server = mock(ServerClient.class); doThrow(new SonarException()).when(server).request("/deploy/plugins/index.txt"); - new PluginDownloader(new BatchSonarCache(new Settings()), server).downloadPluginIndex(); - } - - @Test - public void should_fail_if_invalid_checksum() throws Exception { - thrown.expect(SonarException.class); - thrown.expectMessage("INVALID CHECKSUM"); - - SonarCache cache = mock(SonarCache.class); - BatchSonarCache batchCache = mock(BatchSonarCache.class); - when(batchCache.getCache()).thenReturn(cache); - - File fileInCache = temp.newFile(); - when(cache.cacheFile(Mockito.any(File.class), Mockito.anyString())).thenReturn("fakemd51diff"); - when(cache.getFileFromCache(Mockito.anyString(), Mockito.anyString())) - .thenReturn(null) - .thenReturn(fileInCache); - ServerClient server = mock(ServerClient.class); - PluginDownloader downloader = new PluginDownloader(batchCache, server); - - RemotePlugin plugin = new RemotePlugin("checkstyle", true) - .addFile("checkstyle-plugin.jar", "fakemd51"); - downloader.downloadPlugin(plugin); + new PluginDownloader(mock(FileCache.class), server).downloadPluginIndex(); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/cache/SonarCacheTest.java b/sonar-batch/src/test/java/org/sonar/batch/cache/SonarCacheTest.java deleted file mode 100644 index dce64ba75bb..00000000000 --- a/sonar-batch/src/test/java/org/sonar/batch/cache/SonarCacheTest.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2008-2012 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.cache; - -import org.apache.commons.io.FileUtils; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; - -import java.io.File; -import java.io.IOException; - -import static org.fest.assertions.Assertions.assertThat; - -public class SonarCacheTest { - - @Rule - public TemporaryFolder tempFolder = new TemporaryFolder(); - - private SonarCache cache; - - @Before - public void prepare() throws IOException { - cache = SonarCache.create(tempFolder.newFolder()).build(); - } - - @Test - public void testCacheExternalFile() throws IOException { - // Create a file outside the cache - File fileToCache = tempFolder.newFile(); - FileUtils.write(fileToCache, "Sample data"); - // Put it in the cache - String md5 = cache.cacheFile(fileToCache, "foo.txt"); - // Verify the temporary location was created to do the copy in the cache in 2 stages - File tmpCache = new File(cache.getCacheLocation(), "tmp"); - assertThat(tmpCache).exists(); - // The tmp location should be empty as the file was moved inside the cache - assertThat(tmpCache.list()).isEmpty(); - // Verify it is present in the cache folder - File fileInCache = new File(new File(cache.getCacheLocation(), md5), "foo.txt"); - assertThat(fileInCache).exists(); - String content = FileUtils.readFileToString(fileInCache); - assertThat(content).isEqualTo("Sample data"); - // Now retrieve from cache API - File fileFromCache = cache.getFileFromCache("foo.txt", md5); - assertThat(fileFromCache.getCanonicalPath()).isEqualTo(fileInCache.getCanonicalPath()); - } - - @Test - public void testCacheInternalFile() throws IOException { - // Create a file in the cache temp location - File fileToCache = cache.getTemporaryFile(); - // Verify the temporary location was created - File tmpCache = new File(cache.getCacheLocation(), "tmp"); - assertThat(tmpCache).exists(); - assertThat(tmpCache.list().length).isEqualTo(1); - - FileUtils.write(fileToCache, "Sample data"); - String md5 = cache.cacheFile(fileToCache, "foo.txt"); - // Verify it is present in the cache folder - File fileInCache = new File(new File(cache.getCacheLocation(), md5), "foo.txt"); - assertThat(fileInCache).exists(); - String content = FileUtils.readFileToString(fileInCache); - assertThat(content).isEqualTo("Sample data"); - // Now retrieve from cache API - File fileFromCache = cache.getFileFromCache("foo.txt", md5); - assertThat(fileFromCache.getCanonicalPath()).isEqualTo(fileInCache.getCanonicalPath()); - } - - @Test - public void testGetFileNotInCache() throws IOException { - File fileFromCache = cache.getFileFromCache("foo.txt", "mockmd5"); - assertThat(fileFromCache).isNull(); - } - -} |