Browse Source

SONAR-4748 Introduce a new extension for managing temp files/folders.

tags/4.0
Julien HENRY 10 years ago
parent
commit
18a4c15b06
29 changed files with 611 additions and 260 deletions
  1. 24
    3
      plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/InitialOpenIssuesStackTest.java
  2. 5
    4
      sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchPluginRepository.java
  3. 43
    0
      sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchTempUtils.java
  4. 1
    1
      sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapContainer.java
  5. 5
    4
      sonar-batch/src/main/java/org/sonar/batch/bootstrap/PreviewDatabase.java
  6. 0
    104
      sonar-batch/src/main/java/org/sonar/batch/bootstrap/TempDirectories.java
  7. 5
    3
      sonar-batch/src/main/java/org/sonar/batch/index/Caches.java
  8. 2
    8
      sonar-batch/src/main/java/org/sonar/batch/scan/DefaultProjectBootstrapper.java
  9. 5
    5
      sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ModuleFileSystemInitializer.java
  10. 11
    10
      sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchPluginRepositoryTest.java
  11. 54
    0
      sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchTempUtilsTest.java
  12. 6
    5
      sonar-batch/src/test/java/org/sonar/batch/bootstrap/BootstrapContainerTest.java
  13. 14
    13
      sonar-batch/src/test/java/org/sonar/batch/bootstrap/PreviewDatabaseTest.java
  14. 0
    82
      sonar-batch/src/test/java/org/sonar/batch/bootstrap/TempDirectoriesTest.java
  15. 9
    2
      sonar-batch/src/test/java/org/sonar/batch/index/CacheTest.java
  16. 29
    1
      sonar-batch/src/test/java/org/sonar/batch/index/CachesTest.java
  17. 8
    2
      sonar-batch/src/test/java/org/sonar/batch/index/ComponentDataCacheTest.java
  18. 9
    3
      sonar-batch/src/test/java/org/sonar/batch/index/ComponentDataPersisterTest.java
  19. 9
    2
      sonar-batch/src/test/java/org/sonar/batch/issue/IssueCacheTest.java
  20. 4
    2
      sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/InputFileCacheTest.java
  21. 7
    6
      sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ModuleFileSystemInitializerTest.java
  22. 121
    0
      sonar-core/src/main/java/org/sonar/core/utils/AbstractTempUtils.java
  23. 71
    0
      sonar-core/src/test/java/org/sonar/core/utils/AbstractTempUtilsTest.java
  24. 6
    0
      sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java
  25. 4
    0
      sonar-plugin-api/src/main/java/org/sonar/api/utils/TempFileUtils.java
  26. 60
    0
      sonar-plugin-api/src/main/java/org/sonar/api/utils/TempUtils.java
  27. 2
    0
      sonar-server/src/main/java/org/sonar/server/platform/Platform.java
  28. 41
    0
      sonar-server/src/main/java/org/sonar/server/util/ServerTempUtils.java
  29. 56
    0
      sonar-server/src/test/java/org/sonar/server/util/ServerTempUtilsTest.java

+ 24
- 3
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/InitialOpenIssuesStackTest.java View File

@@ -20,24 +20,45 @@

package org.sonar.plugins.core.issue;

import edu.emory.mathcs.backport.java.util.Collections;
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.CoreProperties;
import org.sonar.batch.bootstrap.BatchTempUtils;
import org.sonar.batch.bootstrap.BootstrapProperties;
import org.sonar.batch.bootstrap.BootstrapSettings;
import org.sonar.batch.index.Caches;
import org.sonar.core.issue.db.IssueDto;

import java.io.IOException;
import java.util.List;

import static com.google.common.collect.Lists.newArrayList;
import static org.fest.assertions.Assertions.assertThat;

public class InitialOpenIssuesStackTest {

@ClassRule
public static TemporaryFolder temp = new TemporaryFolder();

public static Caches createCacheOnTemp(TemporaryFolder temp) {
BootstrapSettings bootstrapSettings = new BootstrapSettings(new BootstrapProperties(Collections.emptyMap()));
try {
bootstrapSettings.properties().put(CoreProperties.WORKING_DIRECTORY, temp.newFolder().getAbsolutePath());
} catch (IOException e) {
throw new RuntimeException(e);
}
return new Caches(new BatchTempUtils(bootstrapSettings));
}

InitialOpenIssuesStack stack;
Caches caches = new Caches();
Caches caches;

@Before
public void setUp() {
public void setUp() throws Exception {
caches = createCacheOnTemp(temp);
caches.start();
stack = new InitialOpenIssuesStack(caches);
}

+ 5
- 4
sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchPluginRepository.java View File

@@ -30,6 +30,7 @@ import org.sonar.api.Plugin;
import org.sonar.api.config.Settings;
import org.sonar.api.platform.PluginMetadata;
import org.sonar.api.platform.PluginRepository;
import org.sonar.api.utils.TempUtils;
import org.sonar.core.plugins.PluginClassloaders;
import org.sonar.core.plugins.PluginInstaller;
import org.sonar.core.plugins.RemotePlugin;
@@ -53,12 +54,12 @@ public class BatchPluginRepository implements PluginRepository {
private Map<String, PluginMetadata> metadataByKey;
private Settings settings;
private PluginClassloaders classLoaders;
private TempDirectories workingDirectories;
private TempUtils tempDirectories;
private final AnalysisMode analysisMode;

public BatchPluginRepository(PluginDownloader pluginDownloader, TempDirectories workingDirectories, Settings settings, AnalysisMode analysisMode) {
public BatchPluginRepository(PluginDownloader pluginDownloader, TempUtils tempDirectories, Settings settings, AnalysisMode analysisMode) {
this.pluginDownloader = pluginDownloader;
this.workingDirectories = workingDirectories;
this.tempDirectories = tempDirectories;
this.settings = settings;
this.analysisMode = analysisMode;
}
@@ -76,7 +77,7 @@ public class BatchPluginRepository implements PluginRepository {
if (filter.accepts(remote.getKey())) {
List<File> pluginFiles = pluginDownloader.downloadPlugin(remote);
List<File> extensionFiles = pluginFiles.subList(1, pluginFiles.size());
File targetDir = workingDirectories.getDir("plugins/" + remote.getKey());
File targetDir = tempDirectories.createDirectory("plugins/" + remote.getKey());
LOG.debug("Installing plugin {} into {}", remote.getKey(), targetDir.getAbsolutePath());
PluginMetadata metadata = extractor.install(pluginFiles.get(0), remote.isCore(), extensionFiles, targetDir);
if (StringUtils.isBlank(metadata.getBasePlugin()) || filter.accepts(metadata.getBasePlugin())) {

+ 43
- 0
sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchTempUtils.java View File

@@ -0,0 +1,43 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2013 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.batch.bootstrap;

import org.apache.commons.io.FileUtils;
import org.sonar.api.CoreProperties;
import org.sonar.core.utils.AbstractTempUtils;

import java.io.File;
import java.io.IOException;

public class BatchTempUtils extends AbstractTempUtils {

public BatchTempUtils(BootstrapSettings bootstrapSettings) {
String workingDirPath = bootstrapSettings.property(CoreProperties.WORKING_DIRECTORY, CoreProperties.WORKING_DIRECTORY_DEFAULT_VALUE);
File workingDir = new File(workingDirPath);
File tempDir = new File(workingDir, "tmp");
try {
FileUtils.forceMkdir(tempDir);
} catch (IOException e) {
throw new IllegalStateException("Unable to create root temp directory " + tempDir, e);
}
setTempDir(tempDir);
}

}

+ 1
- 1
sonar-batch/src/main/java/org/sonar/batch/bootstrap/BootstrapContainer.java View File

@@ -87,7 +87,7 @@ public class BootstrapContainer extends ComponentContainer {
Logback.class,
ServerMetadata.class,
org.sonar.batch.ServerMetadata.class,
TempDirectories.class,
BatchTempUtils.class,
HttpDownloader.class,
UriReader.class,
new FileCacheProvider());

+ 5
- 4
sonar-batch/src/main/java/org/sonar/batch/bootstrap/PreviewDatabase.java View File

@@ -30,6 +30,7 @@ import org.sonar.api.config.Settings;
import org.sonar.api.database.DatabaseProperties;
import org.sonar.api.utils.HttpDownloader.HttpException;
import org.sonar.api.utils.SonarException;
import org.sonar.api.utils.TempUtils;

import java.io.File;
import java.net.SocketTimeoutException;
@@ -50,19 +51,19 @@ public class PreviewDatabase implements BatchComponent {

private final Settings settings;
private final ServerClient server;
private final TempDirectories tempDirectories;
private final TempUtils tempUtils;
private final AnalysisMode mode;

public PreviewDatabase(Settings settings, ServerClient server, TempDirectories tempDirectories, AnalysisMode mode) {
public PreviewDatabase(Settings settings, ServerClient server, TempUtils tempUtils, AnalysisMode mode) {
this.settings = settings;
this.server = server;
this.tempDirectories = tempDirectories;
this.tempUtils = tempUtils;
this.mode = mode;
}

public void start() {
if (mode.isPreview()) {
File databaseFile = tempDirectories.getFile("", "preview.h2.db");
File databaseFile = tempUtils.createTempFile("preview", ".h2.db");

int readTimeoutSec = getReadTimeout();
downloadDatabase(databaseFile, readTimeoutSec * 1000);

+ 0
- 104
sonar-batch/src/main/java/org/sonar/batch/bootstrap/TempDirectories.java View File

@@ -1,104 +0,0 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2013 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.batch.bootstrap;

import com.google.common.collect.Maps;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.AgeFileFilter;
import org.apache.commons.io.filefilter.AndFileFilter;
import org.apache.commons.io.filefilter.DirectoryFileFilter;
import org.apache.commons.io.filefilter.PrefixFileFilter;
import org.apache.commons.lang.StringUtils;
import org.slf4j.LoggerFactory;
import org.sonar.api.utils.SonarException;
import org.sonar.api.utils.TempFileUtils;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;

public class TempDirectories {

public static final String DIR_PREFIX = "sonar-batch";

// this timeout must be greater than the longest analysis
public static final int AGE_BEFORE_DELETION = 24 * 60 * 60 * 1000;

private File rootDir;
private Map<String, File> directoriesByKey = Maps.newHashMap();

public TempDirectories() throws IOException {
this.rootDir = TempFileUtils.createTempDirectory(DIR_PREFIX);
LoggerFactory.getLogger(getClass()).debug("Temporary directory: " + rootDir.getAbsolutePath());
}

public File getRoot() {
return rootDir;
}

/**
* Get or create a working directory
*/
public File getDir(String key) {
if (StringUtils.isBlank(key)) {
return rootDir;
}

File dir = directoriesByKey.get(key);
if (dir == null) {
dir = new File(rootDir, key);
try {
FileUtils.forceMkdir(dir);
directoriesByKey.put(key, dir);

} catch (IOException e) {
throw new SonarException("Can not create the temp directory: " + dir, e);
}
}
return dir;
}

public File getFile(String directoryKey, String filename) {
File dir = getDir(directoryKey);
return new File(dir, filename);
}

/**
* This method is executed by picocontainer during shutdown.
*/
public void stop() {
directoriesByKey.clear();

// Deleting temp directory does not work on MS Windows and Sun JVM because URLClassLoader locks JARs and resources.
// The workaround is that sonar deletes orphans itself.

// older than AGE_BEFORE_DELETION to be sure that the current dir is deleted on mac and linux.
rootDir.setLastModified(System.currentTimeMillis() - AGE_BEFORE_DELETION - 60 * 60 * 1000);

File[] directoriesToDelete = rootDir.getParentFile().listFiles((FileFilter) new AndFileFilter(Arrays.asList(
DirectoryFileFilter.DIRECTORY, new PrefixFileFilter(DIR_PREFIX), new AgeFileFilter(System.currentTimeMillis() - AGE_BEFORE_DELETION))));
for (File dir : directoriesToDelete) {
LoggerFactory.getLogger(getClass()).debug("Delete temporary directory: " + dir);
FileUtils.deleteQuietly(dir);
}
}
}

+ 5
- 3
sonar-batch/src/main/java/org/sonar/batch/index/Caches.java View File

@@ -21,7 +21,6 @@ package org.sonar.batch.index;

import com.google.common.base.Preconditions;
import com.google.common.collect.Sets;
import com.google.common.io.Files;
import com.persistit.Exchange;
import com.persistit.Persistit;
import com.persistit.Volume;
@@ -31,6 +30,7 @@ import org.apache.commons.io.FileUtils;
import org.picocontainer.Startable;
import org.slf4j.LoggerFactory;
import org.sonar.api.BatchComponent;
import org.sonar.api.utils.TempUtils;

import java.io.File;
import java.io.Serializable;
@@ -48,14 +48,16 @@ public class Caches implements BatchComponent, Startable {
private File tempDir;
private Persistit persistit;
private Volume volume;
private final TempUtils tempUtils;

public Caches() {
public Caches(TempUtils tempUtils) {
this.tempUtils = tempUtils;
initPersistit();
}

private void initPersistit() {
try {
tempDir = Files.createTempDir();
tempDir = tempUtils.createTempDirectory("caches");
persistit = new Persistit();
persistit.setPersistitLogger(new Slf4jAdapter(LoggerFactory.getLogger("PERSISTIT")));
Properties props = new Properties();

+ 2
- 8
sonar-batch/src/main/java/org/sonar/batch/scan/DefaultProjectBootstrapper.java View File

@@ -81,12 +81,6 @@ class DefaultProjectBootstrapper implements ProjectBootstrapper {
PROPERTY_OLD_LIBRARIES, PROPERTY_LIBRARIES
);

/**
* @since 1.4
*/
private static final String PROPERTY_WORK_DIRECTORY = "sonar.working.directory";
private static final String DEF_VALUE_WORK_DIRECTORY = ".sonar";

/**
* Array of all mandatory properties required for a project without child.
*/
@@ -151,9 +145,9 @@ class DefaultProjectBootstrapper implements ProjectBootstrapper {

@VisibleForTesting
protected File initRootProjectWorkDir(File baseDir) {
String workDir = settings.property(PROPERTY_WORK_DIRECTORY);
String workDir = settings.property(CoreProperties.WORKING_DIRECTORY);
if (StringUtils.isBlank(workDir)) {
return new File(baseDir, DEF_VALUE_WORK_DIRECTORY);
return new File(baseDir, CoreProperties.WORKING_DIRECTORY_DEFAULT_VALUE);
}

File customWorkDir = new File(workDir);

+ 5
- 5
sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ModuleFileSystemInitializer.java View File

@@ -24,7 +24,7 @@ import org.apache.commons.io.FileUtils;
import org.sonar.api.BatchComponent;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonar.api.scan.filesystem.PathResolver;
import org.sonar.batch.bootstrap.TempDirectories;
import org.sonar.api.utils.TempUtils;

import java.io.File;
import java.util.List;
@@ -41,19 +41,19 @@ public class ModuleFileSystemInitializer implements BatchComponent {
private List<File> additionalSourceFiles;
private List<File> additionalTestFiles;

public ModuleFileSystemInitializer(ProjectDefinition module, TempDirectories tempDirectories, PathResolver pathResolver) {
public ModuleFileSystemInitializer(ProjectDefinition module, TempUtils tempUtils, PathResolver pathResolver) {
baseDir = module.getBaseDir();
buildDir = module.getBuildDir();
initWorkingDir(module, tempDirectories);
initWorkingDir(module, tempUtils);
initBinaryDirs(module, pathResolver);
initSources(module, pathResolver);
initTests(module, pathResolver);
}

private void initWorkingDir(ProjectDefinition module, TempDirectories tempDirectories) {
private void initWorkingDir(ProjectDefinition module, TempUtils tempUtils) {
workingDir = module.getWorkDir();
if (workingDir == null) {
workingDir = tempDirectories.getDir("work");
workingDir = tempUtils.createTempDirectory("work");
} else {
try {
FileUtils.forceMkdir(workingDir);

+ 11
- 10
sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchPluginRepositoryTest.java View File

@@ -28,6 +28,7 @@ import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.CoreProperties;
import org.sonar.api.config.Settings;
import org.sonar.api.utils.TempUtils;
import org.sonar.core.plugins.RemotePlugin;
import org.sonar.core.plugins.RemotePluginFile;
import org.sonar.test.TestUtils;
@@ -63,9 +64,9 @@ public class BatchPluginRepositoryTest {

@Test
public void shouldLoadPlugin() throws IOException {
TempDirectories tempDirs = mock(TempDirectories.class);
TempUtils tempDirs = mock(TempUtils.class);
File toDir = temp.newFolder();
when(tempDirs.getDir("plugins/checkstyle")).thenReturn(toDir);
when(tempDirs.createDirectory("plugins/checkstyle")).thenReturn(toDir);
RemotePlugin checkstyle = new RemotePlugin("checkstyle", true);

PluginDownloader downloader = mock(PluginDownloader.class);
@@ -83,11 +84,11 @@ public class BatchPluginRepositoryTest {

@Test
public void shouldLoadPluginExtension() throws IOException {
TempDirectories tempDirs = mock(TempDirectories.class);
TempUtils tempDirs = mock(TempUtils.class);
File toDir1 = temp.newFolder();
File toDir2 = temp.newFolder();
when(tempDirs.getDir("plugins/checkstyle")).thenReturn(toDir1);
when(tempDirs.getDir("plugins/checkstyleextensions")).thenReturn(toDir2);
when(tempDirs.createDirectory("plugins/checkstyle")).thenReturn(toDir1);
when(tempDirs.createDirectory("plugins/checkstyleextensions")).thenReturn(toDir2);
RemotePlugin checkstyle = new RemotePlugin("checkstyle", true);
RemotePlugin checkstyleExt = new RemotePlugin("checkstyleextensions", false);

@@ -108,9 +109,9 @@ public class BatchPluginRepositoryTest {

@Test
public void shouldLoadPluginDeprecatedExtensions() throws IOException {
TempDirectories tempDirs = mock(TempDirectories.class);
TempUtils tempDirs = mock(TempUtils.class);
File toDir = temp.newFolder();
when(tempDirs.getDir("plugins/checkstyle")).thenReturn(toDir);
when(tempDirs.createDirectory("plugins/checkstyle")).thenReturn(toDir);
RemotePlugin checkstyle = new RemotePlugin("checkstyle", true);
checkstyle.getFiles().add(new RemotePluginFile("checkstyle-ext.xml", "fakemd5"));

@@ -130,11 +131,11 @@ public class BatchPluginRepositoryTest {

@Test
public void shouldExcludePluginAndItsExtensions() throws IOException {
TempDirectories tempDirs = mock(TempDirectories.class);
BatchTempUtils tempDirs = mock(BatchTempUtils.class);
File toDir1 = temp.newFolder();
File toDir2 = temp.newFolder();
when(tempDirs.getDir("plugins/checkstyle")).thenReturn(toDir1);
when(tempDirs.getDir("plugins/checkstyleextensions")).thenReturn(toDir2);
when(tempDirs.createDirectory("plugins/checkstyle")).thenReturn(toDir1);
when(tempDirs.createDirectory("plugins/checkstyleextensions")).thenReturn(toDir2);
RemotePlugin checkstyle = new RemotePlugin("checkstyle", true);
RemotePlugin checkstyleExt = new RemotePlugin("checkstyleextensions", false);


+ 54
- 0
sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchTempUtilsTest.java View File

@@ -0,0 +1,54 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2013 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.batch.bootstrap;

import com.google.common.collect.ImmutableMap;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.CoreProperties;

import java.io.File;

import static org.fest.assertions.Assertions.assertThat;

public class BatchTempUtilsTest {

@Rule
public ExpectedException throwable = ExpectedException.none();

@Rule
public TemporaryFolder temp = new TemporaryFolder();

@Test
public void createTempFolder() throws Exception {
File workingDir = temp.newFolder();
BatchTempUtils tempUtils = new BatchTempUtils(new BootstrapSettings(
new BootstrapProperties(ImmutableMap.of(CoreProperties.WORKING_DIRECTORY, workingDir.getAbsolutePath()))));
tempUtils.createTempDirectory();
tempUtils.createTempFile();
assertThat(new File(workingDir, "tmp")).exists();
assertThat(new File(workingDir, "tmp").list()).hasSize(2);

tempUtils.stop();
assertThat(new File(workingDir, "tmp")).doesNotExist();
}
}

+ 6
- 5
sonar-batch/src/test/java/org/sonar/batch/bootstrap/BootstrapContainerTest.java View File

@@ -42,10 +42,11 @@ public class BootstrapContainerTest {
@Test
public void should_add_components() {
BootstrapContainer container = BootstrapContainer.create(Collections.emptyList());
container.add(new BootstrapProperties(Collections.<String, String>emptyMap()));
container.doBeforeStart();

assertThat(container.getComponentByType(Logback.class)).isNotNull();
assertThat(container.getComponentByType(TempDirectories.class)).isNotNull();
assertThat(container.getComponentByType(BatchTempUtils.class)).isNotNull();
}

@Test
@@ -62,11 +63,11 @@ public class BootstrapContainerTest {
PluginMetadata metadata = mock(PluginMetadata.class);
FakePlugin plugin = new FakePlugin();
BatchPluginRepository pluginRepository = mock(BatchPluginRepository.class);
when(pluginRepository.getPluginsByMetadata()).thenReturn(ImmutableMap.<PluginMetadata, Plugin> of(
metadata, plugin
));
when(pluginRepository.getPluginsByMetadata()).thenReturn(ImmutableMap.<PluginMetadata, Plugin>of(
metadata, plugin
));

BootstrapContainer container = spy(BootstrapContainer.create(Lists.<Object> newArrayList(pluginRepository)));
BootstrapContainer container = spy(BootstrapContainer.create(Lists.<Object>newArrayList(pluginRepository)));
doNothing().when(container).executeTask();
container.doAfterStart();


+ 14
- 13
sonar-batch/src/test/java/org/sonar/batch/bootstrap/PreviewDatabaseTest.java View File

@@ -30,6 +30,7 @@ import org.sonar.api.config.Settings;
import org.sonar.api.database.DatabaseProperties;
import org.sonar.api.utils.HttpDownloader;
import org.sonar.api.utils.SonarException;
import org.sonar.api.utils.TempUtils;

import java.io.File;
import java.net.SocketTimeoutException;
@@ -44,7 +45,7 @@ import static org.mockito.Mockito.when;
public class PreviewDatabaseTest {
Settings settings;
ServerClient server = mock(ServerClient.class);
TempDirectories tempDirectories = mock(TempDirectories.class);
TempUtils tempUtils = mock(TempUtils.class);
File databaseFile;
private AnalysisMode mode;

@@ -57,7 +58,7 @@ public class PreviewDatabaseTest {
@Before
public void setUp() throws Exception {
databaseFile = temp.newFile("preview.h2.db");
when(tempDirectories.getFile("", "preview.h2.db")).thenReturn(databaseFile);
when(tempUtils.createTempFile("preview", ".h2.db")).thenReturn(databaseFile);
settings = new Settings();
settings.setProperty(CoreProperties.PROJECT_KEY_PROPERTY, "group:project");

@@ -68,14 +69,14 @@ public class PreviewDatabaseTest {
@Test
public void should_be_disabled_if_not_preview() {
when(mode.isPreview()).thenReturn(false);
new PreviewDatabase(settings, server, tempDirectories, mode).start();
new PreviewDatabase(settings, server, tempUtils, mode).start();

verifyZeroInteractions(tempDirectories, server);
verifyZeroInteractions(tempUtils, server);
}

@Test
public void should_download_database() {
new PreviewDatabase(settings, server, tempDirectories, mode).start();
new PreviewDatabase(settings, server, tempUtils, mode).start();

verify(server).download("/batch_bootstrap/db?project=group:project", databaseFile, 60000);
}
@@ -83,7 +84,7 @@ public class PreviewDatabaseTest {
@Test
public void should_download_database_with_deprecated_overriden_timeout() {
settings.setProperty(CoreProperties.DRY_RUN_READ_TIMEOUT_SEC, 80);
new PreviewDatabase(settings, server, tempDirectories, mode).start();
new PreviewDatabase(settings, server, tempUtils, mode).start();

verify(server).download("/batch_bootstrap/db?project=group:project", databaseFile, 80000);
}
@@ -91,7 +92,7 @@ public class PreviewDatabaseTest {
@Test
public void should_download_database_with_overriden_timeout() {
settings.setProperty(CoreProperties.PREVIEW_READ_TIMEOUT_SEC, 80);
new PreviewDatabase(settings, server, tempDirectories, mode).start();
new PreviewDatabase(settings, server, tempUtils, mode).start();

verify(server).download("/batch_bootstrap/db?project=group:project", databaseFile, 80000);
}
@@ -99,14 +100,14 @@ public class PreviewDatabaseTest {
@Test
public void should_download_database_on_branch() {
settings.setProperty(CoreProperties.PROJECT_BRANCH_PROPERTY, "mybranch");
new PreviewDatabase(settings, server, tempDirectories, mode).start();
new PreviewDatabase(settings, server, tempUtils, mode).start();

verify(server).download("/batch_bootstrap/db?project=group:project:mybranch", databaseFile, 60000);
}

@Test
public void should_replace_database_settings() {
new PreviewDatabase(settings, server, tempDirectories, mode).start();
new PreviewDatabase(settings, server, tempUtils, mode).start();

assertThat(settings.getString(DatabaseProperties.PROP_DIALECT)).isEqualTo("h2");
assertThat(settings.getString(DatabaseProperties.PROP_DRIVER)).isEqualTo("org.h2.Driver");
@@ -122,7 +123,7 @@ public class PreviewDatabaseTest {
thrown.expect(SonarException.class);
thrown.expectMessage("You don't have access rights to project [group:project]");

new PreviewDatabase(settings, server, tempDirectories, mode).start();
new PreviewDatabase(settings, server, tempUtils, mode).start();
}

@Test
@@ -132,7 +133,7 @@ public class PreviewDatabaseTest {
thrown.expect(SonarException.class);
thrown.expectMessage("Preview database read timed out after 60000 ms. You can try to increase read timeout with property -Dsonar.preview.readTimeout (in seconds)");

new PreviewDatabase(settings, server, tempDirectories, mode).start();
new PreviewDatabase(settings, server, tempUtils, mode).start();
}

@Test
@@ -142,14 +143,14 @@ public class PreviewDatabaseTest {
thrown.expect(SonarException.class);
thrown.expectMessage("BUG");

new PreviewDatabase(settings, server, tempDirectories, mode).start();
new PreviewDatabase(settings, server, tempUtils, mode).start();
}

@Test
public void project_should_be_optional() {
// on non-scan tasks
settings.removeProperty(CoreProperties.PROJECT_KEY_PROPERTY);
new PreviewDatabase(settings, server, tempDirectories, mode).start();
new PreviewDatabase(settings, server, tempUtils, mode).start();
verify(server).download("/batch_bootstrap/db", databaseFile, 60000);
}
}

+ 0
- 82
sonar-batch/src/test/java/org/sonar/batch/bootstrap/TempDirectoriesTest.java View File

@@ -1,82 +0,0 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2013 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.batch.bootstrap;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.File;
import java.io.IOException;

import static org.fest.assertions.Assertions.assertThat;

public class TempDirectoriesTest {

private TempDirectories tempDirectories;

@Before
public void before() throws IOException {
tempDirectories = new TempDirectories();
}

@After
public void after() {
if (tempDirectories != null) {
tempDirectories.stop();
}
}

@Test
public void shouldCreateRoot() {
assertThat(tempDirectories.getRoot()).isNotNull();
assertThat(tempDirectories.getRoot()).exists();
assertThat(tempDirectories.getRoot()).isDirectory();
assertThat(tempDirectories.getDir("")).isEqualTo(tempDirectories.getRoot());
}

@Test
public void shouldCreateDirectory() {
File findbugsDir = tempDirectories.getDir("findbugs");
assertThat(findbugsDir).isNotNull();
assertThat(findbugsDir).exists();
assertThat(findbugsDir.getParentFile()).isEqualTo(tempDirectories.getRoot());
assertThat(findbugsDir.getName()).isEqualTo("findbugs");
}

@Test
public void shouldStopAndDeleteDirectory() {
File root = tempDirectories.getRoot();
File findbugsDir = tempDirectories.getDir("findbugs");
assertThat(findbugsDir).exists();

tempDirectories.stop();

assertThat(root).doesNotExist();
assertThat(findbugsDir).doesNotExist();
}

@Test
public void shouldCreateDirectoryWhenGettingFile() {
File file = tempDirectories.getFile("findbugs", "bcel.jar");
assertThat(file).isNotNull();
assertThat(file.getParentFile().getName()).isEqualTo("findbugs");
}
}

+ 9
- 2
sonar-batch/src/test/java/org/sonar/batch/index/CacheTest.java View File

@@ -23,15 +23,22 @@ import com.google.common.collect.Iterables;
import com.persistit.exception.PersistitException;
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import static org.fest.assertions.Assertions.assertThat;

public class CacheTest {
Caches caches = new Caches();

@ClassRule
public static TemporaryFolder temp = new TemporaryFolder();

Caches caches;

@Before
public void start() {
public void start() throws Exception {
caches = CachesTest.createCacheOnTemp(temp);
caches.start();
}


+ 29
- 1
sonar-batch/src/test/java/org/sonar/batch/index/CachesTest.java View File

@@ -19,17 +19,45 @@
*/
package org.sonar.batch.index;

import edu.emory.mathcs.backport.java.util.Collections;
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.CoreProperties;
import org.sonar.batch.bootstrap.BatchTempUtils;
import org.sonar.batch.bootstrap.BootstrapProperties;
import org.sonar.batch.bootstrap.BootstrapSettings;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;

import static org.fest.assertions.Assertions.assertThat;
import static org.fest.assertions.Fail.fail;

public class CachesTest {
Caches caches = new Caches();

@ClassRule
public static TemporaryFolder temp = new TemporaryFolder();

public static Caches createCacheOnTemp(TemporaryFolder temp) {
BootstrapSettings bootstrapSettings = new BootstrapSettings(new BootstrapProperties(Collections.emptyMap()));
try {
bootstrapSettings.properties().put(CoreProperties.WORKING_DIRECTORY, temp.newFolder().getAbsolutePath());
} catch (IOException e) {
throw new RuntimeException(e);
}
return new Caches(new BatchTempUtils(bootstrapSettings));
}

Caches caches;

@Before
public void prepare() throws Exception {
caches = createCacheOnTemp(temp);
}

@After
public void stop() {

+ 8
- 2
sonar-batch/src/test/java/org/sonar/batch/index/ComponentDataCacheTest.java View File

@@ -21,16 +21,22 @@ package org.sonar.batch.index;

import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import static org.fest.assertions.Assertions.assertThat;

public class ComponentDataCacheTest {

Caches caches = new Caches();
@ClassRule
public static TemporaryFolder temp = new TemporaryFolder();

Caches caches;

@Before
public void start() {
public void start() throws Exception {
caches = CachesTest.createCacheOnTemp(temp);
caches.start();
}


+ 9
- 3
sonar-batch/src/test/java/org/sonar/batch/index/ComponentDataPersisterTest.java View File

@@ -21,19 +21,25 @@ package org.sonar.batch.index;

import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.database.model.Snapshot;
import org.sonar.core.persistence.AbstractDaoTestCase;
import org.sonar.core.source.jdbc.SnapshotDataDao;

public class ComponentDataPersisterTest extends AbstractDaoTestCase {

@ClassRule
public static TemporaryFolder temp = new TemporaryFolder();

SnapshotCache snapshots = new SnapshotCache();
ComponentDataCache data;
Caches caches = new Caches();
Caches caches;

@Before
public void start() {
public void start() throws Exception {
caches = CachesTest.createCacheOnTemp(temp);
caches.start();
}

@@ -59,6 +65,6 @@ public class ComponentDataPersisterTest extends AbstractDaoTestCase {
ComponentDataPersister persister = new ComponentDataPersister(data, snapshots, dataDao, getMyBatis());
persister.persist();

checkTables("should_persist_component_data", new String[]{"id", "created_at", "updated_at"}, "snapshot_data");
checkTables("should_persist_component_data", new String[] {"id", "created_at", "updated_at"}, "snapshot_data");
}
}

+ 9
- 2
sonar-batch/src/test/java/org/sonar/batch/issue/IssueCacheTest.java View File

@@ -24,11 +24,14 @@ import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableList;
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.internal.DefaultIssue;
import org.sonar.api.rule.Severity;
import org.sonar.batch.index.Caches;
import org.sonar.batch.index.CachesTest;

import javax.annotation.Nullable;

@@ -39,10 +42,14 @@ import static org.fest.assertions.Assertions.assertThat;

public class IssueCacheTest {

Caches caches = new Caches();
@ClassRule
public static TemporaryFolder temp = new TemporaryFolder();

Caches caches;

@Before
public void start() {
public void start() throws Exception {
caches = CachesTest.createCacheOnTemp(temp);
caches.start();
}


+ 4
- 2
sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/InputFileCacheTest.java View File

@@ -28,6 +28,7 @@ import org.junit.rules.TemporaryFolder;
import org.sonar.api.scan.filesystem.InputFile;
import org.sonar.api.scan.filesystem.internal.DefaultInputFile;
import org.sonar.batch.index.Caches;
import org.sonar.batch.index.CachesTest;

import static org.fest.assertions.Assertions.assertThat;

@@ -36,10 +37,11 @@ public class InputFileCacheTest {
@Rule
public TemporaryFolder temp = new TemporaryFolder();

Caches caches = new Caches();
Caches caches;

@Before
public void start() {
public void start() throws Exception {
caches = CachesTest.createCacheOnTemp(temp);
caches.start();
}


+ 7
- 6
sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ModuleFileSystemInitializerTest.java View File

@@ -21,22 +21,23 @@ package org.sonar.batch.scan.filesystem;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.junit.Rule;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonar.api.scan.filesystem.PathResolver;
import org.sonar.batch.bootstrap.TempDirectories;
import org.sonar.api.utils.TempUtils;

import java.io.File;
import java.io.IOException;

import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Mockito.mock;

public class ModuleFileSystemInitializerTest {

@Rule
public TemporaryFolder temp = new TemporaryFolder();
@ClassRule
public static TemporaryFolder temp = new TemporaryFolder();

PathResolver pathResolver = new PathResolver();

@@ -46,7 +47,7 @@ public class ModuleFileSystemInitializerTest {
File workDir = temp.newFolder("work");
ProjectDefinition module = ProjectDefinition.create().setBaseDir(baseDir).setWorkDir(workDir);

ModuleFileSystemInitializer initializer = new ModuleFileSystemInitializer(module, new TempDirectories(), pathResolver);
ModuleFileSystemInitializer initializer = new ModuleFileSystemInitializer(module, mock(TempUtils.class), pathResolver);

assertThat(initializer.baseDir().getCanonicalPath()).isEqualTo(baseDir.getCanonicalPath());
assertThat(initializer.workingDir().getCanonicalPath()).isEqualTo(workDir.getCanonicalPath());
@@ -72,7 +73,7 @@ public class ModuleFileSystemInitializerTest {
.addTestDirs("src/test/java", "src/test/unknown")
.addBinaryDir("target/classes");

ModuleFileSystemInitializer initializer = new ModuleFileSystemInitializer(project, new TempDirectories(), pathResolver);
ModuleFileSystemInitializer initializer = new ModuleFileSystemInitializer(project, mock(TempUtils.class), pathResolver);

assertThat(initializer.baseDir().getCanonicalPath()).isEqualTo(baseDir.getCanonicalPath());
assertThat(initializer.buildDir().getCanonicalPath()).isEqualTo(buildDir.getCanonicalPath());

+ 121
- 0
sonar-core/src/main/java/org/sonar/core/utils/AbstractTempUtils.java View File

@@ -0,0 +1,121 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2013 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.core.utils;

import org.apache.commons.io.FileUtils;
import org.picocontainer.Startable;
import org.sonar.api.utils.TempUtils;

import javax.annotation.Nullable;

import java.io.File;
import java.io.IOException;

public abstract class AbstractTempUtils implements TempUtils, Startable {

/** Maximum loop count when creating temp directories. */
private static final int TEMP_DIR_ATTEMPTS = 10000;

private File tempDir;

protected void setTempDir(File tempDir) {
this.tempDir = tempDir;
}

@Override
public File createTempDirectory() {
return createTempDirectory(null);
}

@Override
public File createTempDirectory(@Nullable String prefix) {
return createTempDir(tempDir, prefix);
}

/**
* Copied from guava waiting for JDK 7 Files#createTempDirectory
*/
private static File createTempDir(File baseDir, String prefix) {
String baseName = prefix + System.currentTimeMillis() + "-";

for (int counter = 0; counter < TEMP_DIR_ATTEMPTS; counter++) {
File tempDir = new File(baseDir, baseName + counter);
if (tempDir.mkdir()) {
return tempDir;
}
}
throw new IllegalStateException("Failed to create directory within "
+ TEMP_DIR_ATTEMPTS + " attempts (tried "
+ baseName + "0 to " + baseName + (TEMP_DIR_ATTEMPTS - 1) + ')');
}

@Override
public File createDirectory(String name) {
File dir = new File(tempDir, name);
try {
FileUtils.forceMkdir(dir);
} catch (IOException e) {
throw new IllegalStateException("Unable to create temp directory in " + dir, e);
}
return dir;
}

@Override
public File createTempFile() {
return createTempFile(null, null);
}

@Override
public File createTempFile(@Nullable String prefix, @Nullable String suffix) {
return createTempFile(tempDir, prefix, suffix);
}

/**
* Inspired by guava waiting for JDK 7 Files#createTempFile
*/
private static File createTempFile(File baseDir, String prefix, String suffix) {
String baseName = prefix + System.currentTimeMillis() + "-";

try {
for (int counter = 0; counter < TEMP_DIR_ATTEMPTS; counter++) {
File tempFile = new File(baseDir, baseName + counter + suffix);
if (tempFile.createNewFile()) {
return tempFile;
}
}
} catch (IOException e) {
throw new IllegalStateException("Failed to create temp file", e);
}
throw new IllegalStateException("Failed to create temp file within "
+ TEMP_DIR_ATTEMPTS + " attempts (tried "
+ baseName + "0" + suffix + " to " + baseName + (TEMP_DIR_ATTEMPTS - 1) + suffix + ")");
}

@Override
public void start() {
// Nothing to do
}

@Override
public void stop() {
FileUtils.deleteQuietly(tempDir);
}

}

+ 71
- 0
sonar-core/src/test/java/org/sonar/core/utils/AbstractTempUtilsTest.java View File

@@ -0,0 +1,71 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2013 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.core.utils;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;

import java.io.File;

import static org.fest.assertions.Assertions.assertThat;

public class AbstractTempUtilsTest {

@Rule
public ExpectedException throwable = ExpectedException.none();

@Rule
public TemporaryFolder temp = new TemporaryFolder();

@Test
public void createTempFolderAndFile() throws Exception {
File tempFolder = temp.newFolder();
AbstractTempUtils tempUtils = new CustomTempUtils(tempFolder);
File dir = tempUtils.createTempDirectory();
assertThat(dir).exists().isDirectory();
File file = tempUtils.createTempFile();
assertThat(file).exists().isFile();

tempUtils.stop();
assertThat(tempFolder).doesNotExist();
}

@Test
public void createTempFolderWithName() throws Exception {
File tempFolder = temp.newFolder();
AbstractTempUtils tempUtils = new CustomTempUtils(tempFolder);
File dir = tempUtils.createDirectory("sample");
assertThat(dir).exists().isDirectory();
assertThat(new File(tempFolder, "sample")).isEqualTo(dir);

tempUtils.stop();
assertThat(tempFolder).doesNotExist();
}

private static class CustomTempUtils extends AbstractTempUtils {

public CustomTempUtils(File tempDir) {
setTempDir(tempDir);
}

}
}

+ 6
- 0
sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java View File

@@ -522,4 +522,10 @@ public interface CoreProperties {
*/
String PREVIEW_EXCLUDE_PLUGINS = "sonar.preview.excludePlugins";
String PREVIEW_EXCLUDE_PLUGINS_DEFAULT_VALUE = "devcockpit,pdfreport,report,scmactivity,views,jira";

/**
* @since 4.0
*/
String WORKING_DIRECTORY = "sonar.working.directory";
String WORKING_DIRECTORY_DEFAULT_VALUE = ".sonar";
}

+ 4
- 0
sonar-plugin-api/src/main/java/org/sonar/api/utils/TempFileUtils.java View File

@@ -22,6 +22,10 @@ package org.sonar.api.utils;
import java.io.File;
import java.io.IOException;

/**
* @deprecated since 4.0 use {@link TempUtils}
*/
@Deprecated
public final class TempFileUtils {

private TempFileUtils() {

+ 60
- 0
sonar-plugin-api/src/main/java/org/sonar/api/utils/TempUtils.java View File

@@ -0,0 +1,60 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2013 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.api.utils;

import org.sonar.api.ServerComponent;
import org.sonar.api.task.TaskComponent;

import javax.annotation.Nullable;

import java.io.File;

/**
* Use this component to deal with temp files/folders. Root location of temp files/folders
* depends on situation:
* <ul>
* <li>${SONAR_HOME}/temp on server side</li>
* <li>Working directory on batch side (see sonar.working.directory)</li>
* </ul>
* @since 4.0
*
*/
public interface TempUtils extends TaskComponent, ServerComponent {

/**
* Create a directory in temp folder with a random unique name.
*/
File createTempDirectory();

/**
* Create a directory in temp folder with a random unique name and using the provided prefix when possible.
*/
File createTempDirectory(@Nullable String prefix);

/**
* Create a directory in temp folder using provided name.
*/
File createDirectory(String name);

File createTempFile();

File createTempFile(@Nullable String prefix, @Nullable String suffix);

}

+ 2
- 0
sonar-server/src/main/java/org/sonar/server/platform/Platform.java View File

@@ -148,6 +148,7 @@ import org.sonar.server.ui.SecurityRealmFactory;
import org.sonar.server.ui.Views;
import org.sonar.server.user.DefaultUserService;
import org.sonar.server.user.NewUserNotifier;
import org.sonar.server.util.ServerTempUtils;

import javax.servlet.ServletContext;

@@ -239,6 +240,7 @@ public final class Platform {
rootContainer.addSingleton(PreviewDatabaseFactory.class);
rootContainer.addSingleton(SemaphoreUpdater.class);
rootContainer.addSingleton(SemaphoresImpl.class);
rootContainer.addSingleton(ServerTempUtils.class);
rootContainer.startComponents();
}


+ 41
- 0
sonar-server/src/main/java/org/sonar/server/util/ServerTempUtils.java View File

@@ -0,0 +1,41 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2013 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.server.util;

import org.apache.commons.io.FileUtils;
import org.sonar.api.platform.ServerFileSystem;
import org.sonar.core.utils.AbstractTempUtils;

import java.io.File;
import java.io.IOException;

public class ServerTempUtils extends AbstractTempUtils {

public ServerTempUtils(ServerFileSystem fs) {
File tempDir = new File(fs.getTempDir(), "tmp");
try {
FileUtils.forceMkdir(tempDir);
} catch (IOException e) {
throw new IllegalStateException("Unable to create root temp directory " + tempDir, e);
}
setTempDir(tempDir);
}

}

+ 56
- 0
sonar-server/src/test/java/org/sonar/server/util/ServerTempUtilsTest.java View File

@@ -0,0 +1,56 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2013 SonarSource
* mailto:contact AT sonarsource DOT com
*
* SonarQube 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.
*
* SonarQube 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 this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.server.util;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.platform.ServerFileSystem;

import java.io.File;

import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class ServerTempUtilsTest {

@Rule
public ExpectedException throwable = ExpectedException.none();

@Rule
public TemporaryFolder temp = new TemporaryFolder();

@Test
public void createTempFolder() throws Exception {
ServerFileSystem fs = mock(ServerFileSystem.class);
File serverTempFolder = temp.newFolder();
when(fs.getTempDir()).thenReturn(serverTempFolder);
ServerTempUtils tempUtils = new ServerTempUtils(fs);
tempUtils.createTempDirectory();
tempUtils.createTempFile();
assertThat(new File(serverTempFolder, "tmp")).exists();
assertThat(new File(serverTempFolder, "tmp").list()).hasSize(2);

tempUtils.stop();
assertThat(new File(serverTempFolder, "tmp")).doesNotExist();
}
}

Loading…
Cancel
Save