aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-batch
diff options
context:
space:
mode:
Diffstat (limited to 'sonar-batch')
-rw-r--r--sonar-batch/pom.xml8
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchSonarCache.java58
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapModule.java2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/FileCacheProvider.java38
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/JdbcDriverHolder.java53
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/PluginDownloader.java50
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/cache/SonarCache.java209
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/bootstrap/FileCacheProviderTest.java47
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/bootstrap/JdbcDriverHolderTest.java44
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/bootstrap/PluginDownloaderTest.java82
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/cache/SonarCacheTest.java94
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();
- }
-
-}