Browse Source

SONAR-6649 Move initialization of persistit cache to global context

tags/5.2-RC1
Duarte Meneses 9 years ago
parent
commit
12a57c668b
24 changed files with 681 additions and 324 deletions
  1. 1
    1
      pom.xml
  2. 0
    1
      server/sonar-server/src/main/java/org/sonar/server/platform/TempFolderProvider.java
  3. 4
    0
      sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalContainer.java
  4. 52
    0
      sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectTempFolderProvider.java
  5. 34
    10
      sonar-batch/src/main/java/org/sonar/batch/bootstrap/TempFolderProvider.java
  6. 6
    0
      sonar-batch/src/main/java/org/sonar/batch/bootstrapper/LoggingConfiguration.java
  7. 27
    61
      sonar-batch/src/main/java/org/sonar/batch/index/Caches.java
  8. 98
    0
      sonar-batch/src/main/java/org/sonar/batch/index/CachesManager.java
  9. 8
    1
      sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java
  10. 70
    0
      sonar-batch/src/test/java/org/sonar/batch/bootstrap/ProjectTempFolderProviderTest.java
  11. 42
    13
      sonar-batch/src/test/java/org/sonar/batch/bootstrap/TempFolderProviderTest.java
  12. 3
    23
      sonar-batch/src/test/java/org/sonar/batch/duplication/DuplicationCacheTest.java
  13. 59
    0
      sonar-batch/src/test/java/org/sonar/batch/index/AbstractCachesTest.java
  14. 1
    21
      sonar-batch/src/test/java/org/sonar/batch/index/CacheTest.java
  15. 72
    0
      sonar-batch/src/test/java/org/sonar/batch/index/CachesManagerTest.java
  16. 45
    55
      sonar-batch/src/test/java/org/sonar/batch/index/CachesTest.java
  17. 3
    23
      sonar-batch/src/test/java/org/sonar/batch/issue/IssueCacheTest.java
  18. 3
    25
      sonar-batch/src/test/java/org/sonar/batch/issue/tracking/InitialOpenIssuesStackTest.java
  19. 73
    87
      sonar-batch/src/test/java/org/sonar/batch/scan/measure/MeasureCacheTest.java
  20. 8
    0
      sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java
  21. 54
    0
      sonar-plugin-api/src/main/java/org/sonar/api/utils/ProjectTempFolder.java
  22. 1
    1
      sonar-plugin-api/src/main/java/org/sonar/api/utils/TempFolder.java
  23. 14
    1
      sonar-plugin-api/src/main/java/org/sonar/api/utils/internal/DefaultTempFolder.java
  24. 3
    1
      sonar-plugin-api/src/main/java/org/sonar/api/utils/internal/JUnitTempFolder.java

+ 1
- 1
pom.xml View File

@@ -1093,7 +1093,7 @@
<dependency>
<groupId>org.codehaus.sonar</groupId>
<artifactId>sonar-persistit</artifactId>
<version>3.3.1</version>
<version>3.3.2-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>

+ 0
- 1
server/sonar-server/src/main/java/org/sonar/server/platform/TempFolderProvider.java View File

@@ -44,5 +44,4 @@ public class TempFolderProvider extends ProviderAdapter {
}
return tempFolder;
}

}

+ 4
- 0
sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalContainer.java View File

@@ -19,8 +19,11 @@
*/
package org.sonar.batch.bootstrap;

import org.sonar.batch.index.CachesManager;

import java.util.List;
import java.util.Map;

import org.sonar.api.CoreProperties;
import org.sonar.api.Plugin;
import org.sonar.api.utils.Durations;
@@ -98,6 +101,7 @@ public class GlobalContainer extends ComponentContainer {
BatchPluginPredicate.class,
ExtensionInstaller.class,

CachesManager.class,
GlobalSettings.class,
ServerClient.class,
Logback.class,

+ 52
- 0
sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectTempFolderProvider.java View File

@@ -0,0 +1,52 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 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.sonar.api.utils.ProjectTempFolder;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.picocontainer.injectors.ProviderAdapter;
import org.sonar.api.CoreProperties;
import org.sonar.api.utils.internal.DefaultTempFolder;

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

public class ProjectTempFolderProvider extends ProviderAdapter {
static final String TMP_NAME = ".sonartmp";
private ProjectTempFolder projectTempFolder;

public ProjectTempFolder provide(BootstrapProperties bootstrapProps) {
if (projectTempFolder == null) {
String workingDirPath = StringUtils.defaultIfBlank(bootstrapProps.property(CoreProperties.WORKING_DIRECTORY), CoreProperties.WORKING_DIRECTORY_DEFAULT_VALUE);
File workingDir = new File(workingDirPath).getAbsoluteFile();
File tempDir = new File(workingDir, TMP_NAME);
try {
FileUtils.forceMkdir(tempDir);
} catch (IOException e) {
throw new IllegalStateException("Unable to create root temp directory " + tempDir, e);
}
projectTempFolder = new DefaultTempFolder(tempDir, true);
}
return projectTempFolder;
}

}

+ 34
- 10
sonar-batch/src/main/java/org/sonar/batch/bootstrap/TempFolderProvider.java View File

@@ -19,33 +19,57 @@
*/
package org.sonar.batch.bootstrap;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.utils.TempFolder;
import org.picocontainer.injectors.ProviderAdapter;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.CoreProperties;
import org.sonar.api.utils.TempFolder;
import org.sonar.api.utils.internal.DefaultTempFolder;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class TempFolderProvider extends ProviderAdapter {

static final String TMP_NAME = ".sonartmp";
private TempFolder tempFolder;

public TempFolder provide(BootstrapProperties bootstrapProps) {
if (tempFolder == null) {
String workingDirPath = StringUtils.defaultIfBlank(bootstrapProps.property(CoreProperties.WORKING_DIRECTORY), CoreProperties.WORKING_DIRECTORY_DEFAULT_VALUE);
File workingDir = new File(workingDirPath).getAbsoluteFile();
File tempDir = new File(workingDir, ".sonartmp");

String workingPathName = StringUtils.defaultIfBlank(bootstrapProps.property(CoreProperties.GLOBAL_WORKING_DIRECTORY), CoreProperties.GLOBAL_WORKING_DIRECTORY_DEFAULT_VALUE);
Path workingPath = Paths.get(workingPathName).normalize();

if (!workingPath.isAbsolute()) {
Path home = findHome(bootstrapProps);
workingPath = home.resolve(workingPath).normalize();
}

Path tempDir = workingPath.resolve(TMP_NAME);
try {
FileUtils.forceMkdir(tempDir);
Files.createDirectories(tempDir);
} catch (IOException e) {
throw new IllegalStateException("Unable to create root temp directory " + tempDir, e);
}
tempFolder = new DefaultTempFolder(tempDir);
tempFolder = new DefaultTempFolder(tempDir.toFile(), true);
}
return tempFolder;
}

private static Path findHome(BootstrapProperties props) {
String home = props.property("sonar.userHome");
if (home != null) {
return Paths.get(home);
}

home = System.getenv("SONAR_USER_HOME");

if (home != null) {
return Paths.get(home);
}

home = System.getProperty("user.home");
return Paths.get(home, ".sonar");
}

}

+ 6
- 0
sonar-batch/src/main/java/org/sonar/batch/bootstrapper/LoggingConfiguration.java View File

@@ -27,6 +27,7 @@ import org.sonar.core.config.Logback;
import javax.annotation.Nullable;

import java.io.File;
import java.io.PrintStream;
import java.util.Map;

/**
@@ -72,6 +73,11 @@ public final class LoggingConfiguration {
setVerbose(verbose);
return this;
}
public LoggingConfiguration setStreams(PrintStream out, PrintStream err) {
return this;
}

public LoggingConfiguration setVerbose(boolean verbose) {
return setRootLevel(verbose ? LEVEL_ROOT_VERBOSE : LEVEL_ROOT_DEFAULT);

+ 27
- 61
sonar-batch/src/main/java/org/sonar/batch/index/Caches.java View File

@@ -19,64 +19,40 @@
*/
package org.sonar.batch.index;

import com.google.common.collect.Maps;

import java.util.Map;
import java.util.Map.Entry;

import com.google.common.base.Preconditions;
import com.google.common.collect.Sets;
import com.persistit.Exchange;
import com.persistit.Persistit;
import com.persistit.Value;
import com.persistit.Volume;
import com.persistit.encoding.CoderManager;
import com.persistit.Persistit;
import com.persistit.encoding.ValueCoder;
import com.persistit.exception.PersistitException;
import com.persistit.logging.Slf4jAdapter;
import org.apache.commons.io.FileUtils;
import com.persistit.Volume;
import org.picocontainer.Startable;
import org.slf4j.LoggerFactory;
import org.sonar.api.batch.BatchSide;
import org.sonar.api.utils.TempFolder;

import java.io.File;
import java.util.Properties;
import java.util.Set;

/**
* Factory of caches
*
* @since 3.6
*/
@BatchSide
public class Caches implements Startable {

private final Set<String> cacheNames = Sets.newHashSet();
private File tempDir;
private final Map<String, Exchange> caches = Maps.newHashMap();
private Persistit persistit;
private Volume volume;
private final TempFolder tempFolder;

public Caches(TempFolder tempFolder) {
this.tempFolder = tempFolder;
initPersistit();
public Caches(CachesManager caches) {
persistit = caches.persistit();
start();
}

private void initPersistit() {
@Override
public void start() {
try {
tempDir = tempFolder.newDir("caches");
persistit = new Persistit();
persistit.setPersistitLogger(new Slf4jAdapter(LoggerFactory.getLogger("PERSISTIT")));
Properties props = new Properties();
props.setProperty("datapath", tempDir.getAbsolutePath());
props.setProperty("logpath", "${datapath}/log");
props.setProperty("logfile", "${logpath}/persistit_${timestamp}.log");
props.setProperty("buffer.count.8192", "10");
props.setProperty("journalpath", "${datapath}/journal");
props.setProperty("tmpvoldir", "${datapath}");
props.setProperty("volume.1", "${datapath}/persistit,create,pageSize:8192,initialPages:10,extensionPages:100,maximumPages:25000");
persistit.setProperties(props);
persistit.initialize();
persistit.flush();
volume = persistit.createTemporaryVolume();

} catch (Exception e) {
throw new IllegalStateException("Fail to start caches", e);
throw new IllegalStateException("Fail to create a cache volume", e);
}
}

@@ -87,44 +63,34 @@ public class Caches implements Startable {

public <V> Cache<V> createCache(String cacheName) {
Preconditions.checkState(volume != null && volume.isOpened(), "Caches are not initialized");
Preconditions.checkState(!cacheNames.contains(cacheName), "Cache is already created: " + cacheName);
Preconditions.checkState(!caches.containsKey(cacheName), "Cache is already created: " + cacheName);
try {
Exchange exchange = persistit.getExchange(volume, cacheName, true);
exchange.setMaximumValueSize(Value.MAXIMUM_SIZE);
Cache<V> cache = new Cache<>(cacheName, exchange);
cacheNames.add(cacheName);
caches.put(cacheName, exchange);
return cache;
} catch (Exception e) {
throw new IllegalStateException("Fail to create cache: " + cacheName, e);
}
}

@Override
public void start() {
// already started in constructor
}

@Override
public void stop() {
if (persistit != null) {
for (Entry<String, Exchange> e : caches.entrySet()) {
persistit.releaseExchange(e.getValue());
}

caches.clear();

if (volume != null) {
try {
persistit.close(false);
persistit = null;
volume = null;
volume.close();
volume.delete();
} catch (PersistitException e) {
throw new IllegalStateException("Fail to close caches", e);
}
volume = null;
}
FileUtils.deleteQuietly(tempDir);
tempDir = null;
cacheNames.clear();
}

File tempDir() {
return tempDir;
}

Persistit persistit() {
return persistit;
}
}

+ 98
- 0
sonar-batch/src/main/java/org/sonar/batch/index/CachesManager.java View File

@@ -0,0 +1,98 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 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.index;

import org.sonar.api.utils.TempFolder;

import com.persistit.Persistit;
import com.persistit.exception.PersistitException;
import com.persistit.logging.Slf4jAdapter;
import org.apache.commons.io.FileUtils;
import org.picocontainer.Startable;
import org.slf4j.LoggerFactory;
import org.sonar.api.batch.BatchSide;

import java.io.File;
import java.util.Properties;

/**
* Factory of caches
*
* @since 3.6
*/
@BatchSide
public class CachesManager implements Startable {
private File tempDir;
private Persistit persistit;
private final TempFolder tempFolder;

public CachesManager(TempFolder tempFolder) {
this.tempFolder = tempFolder;
initPersistit();
}

private void initPersistit() {
try {
tempDir = tempFolder.newDir("caches");
persistit = new Persistit();
persistit.setPersistitLogger(new Slf4jAdapter(LoggerFactory.getLogger("PERSISTIT")));
Properties props = new Properties();
props.setProperty("datapath", tempDir.getAbsolutePath());
props.setProperty("logpath", "${datapath}/log");
props.setProperty("logfile", "${logpath}/persistit_${timestamp}.log");
props.setProperty("buffer.count.8192", "10");
props.setProperty("journalpath", "${datapath}/journal");
props.setProperty("tmpvoldir", "${datapath}");
props.setProperty("volume.1", "${datapath}/persistit,create,pageSize:8192,initialPages:10,extensionPages:100,maximumPages:25000");
persistit.setProperties(props);
persistit.initialize();

} catch (Exception e) {
throw new IllegalStateException("Fail to start caches", e);
}
}

@Override
public void start() {
// already started in constructor
}

@Override
public void stop() {
if (persistit != null) {
try {
persistit.close(false);
persistit = null;
} catch (PersistitException e) {
throw new IllegalStateException("Fail to close caches", e);
}
}
FileUtils.deleteQuietly(tempDir);
tempDir = null;
}

File tempDir() {
return tempDir;
}

Persistit persistit() {
return persistit;
}
}

+ 8
- 1
sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java View File

@@ -19,6 +19,10 @@
*/
package org.sonar.batch.scan;

import org.sonar.batch.bootstrap.ProjectTempFolderProvider;

import org.sonar.api.utils.internal.TempFolderCleaner;
import org.sonar.batch.bootstrap.TempFolderProvider;
import com.google.common.annotations.VisibleForTesting;
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.InstantiationStrategy;
@@ -151,7 +155,10 @@ public class ProjectScanContainer extends ComponentContainer {
Caches.class,
BatchComponentCache.class,

// file system
//temp
new ProjectTempFolderProvider(),
// file system
InputPathCache.class,
PathResolver.class,


+ 70
- 0
sonar-batch/src/test/java/org/sonar/batch/bootstrap/ProjectTempFolderProviderTest.java View File

@@ -0,0 +1,70 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 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.utils.ProjectTempFolder;
import com.google.common.collect.ImmutableMap;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.CoreProperties;

import java.io.File;
import java.io.IOException;
import java.util.Collections;

import static org.assertj.core.api.Assertions.assertThat;

public class ProjectTempFolderProviderTest {

@Rule
public TemporaryFolder temp = new TemporaryFolder();

private ProjectTempFolderProvider tempFolderProvider = new ProjectTempFolderProvider();

@Test
public void createTempFolderWithProps() throws Exception {
File workingDir = temp.newFolder();
File tmpDir = new File(workingDir, ProjectTempFolderProvider.TMP_NAME);

ProjectTempFolder tempFolder = tempFolderProvider.provide(new BootstrapProperties(ImmutableMap.of(CoreProperties.WORKING_DIRECTORY, workingDir.getAbsolutePath())));
tempFolder.newDir();
tempFolder.newFile();
assertThat(tmpDir).exists();
assertThat(tmpDir.list()).hasSize(2);
}

@Test
public void createTempFolder() throws IOException {
File defaultDir = new File(CoreProperties.WORKING_DIRECTORY_DEFAULT_VALUE, ProjectTempFolderProvider.TMP_NAME);

try {
ProjectTempFolder tempFolder = tempFolderProvider.provide(new BootstrapProperties(Collections.<String, String>emptyMap()));
tempFolder.newDir();
tempFolder.newFile();
assertThat(defaultDir).exists();
assertThat(defaultDir.list()).hasSize(2);
} finally {
FileUtils.deleteDirectory(defaultDir);
}
}
}

+ 42
- 13
sonar-batch/src/test/java/org/sonar/batch/bootstrap/TempFolderProviderTest.java View File

@@ -19,34 +19,63 @@
*/
package org.sonar.batch.bootstrap;

import org.apache.commons.io.FileUtils;
import org.sonar.api.utils.TempFolder;
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 org.sonar.api.utils.TempFolder;

import java.io.File;
import java.util.Collections;

import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

public class TempFolderProviderTest {

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

@Rule
public TemporaryFolder temp = new TemporaryFolder();

private TempFolderProvider tempFolderProvider = new TempFolderProvider();

@Test
public void createTempFolder() throws Exception {
public void createTempFolderProps() throws Exception {
File workingDir = temp.newFolder();
TempFolderProvider tempFolderProvider = new TempFolderProvider();
TempFolder tempFolder = tempFolderProvider.provide(new BootstrapProperties(ImmutableMap.of(CoreProperties.WORKING_DIRECTORY, workingDir.getAbsolutePath())));
TempFolder tempFolder = tempFolderProvider.provide(new BootstrapProperties(ImmutableMap.of(CoreProperties.GLOBAL_WORKING_DIRECTORY, workingDir.getAbsolutePath())));
tempFolder.newDir();
tempFolder.newFile();
assertThat(new File(workingDir, ".sonartmp")).exists();
assertThat(new File(workingDir, TempFolderProvider.TMP_NAME)).exists();
assertThat(new File(workingDir, ".sonartmp").list()).hasSize(2);
}

@Test
public void createTempFolderSonarHome() throws Exception {
// with sonar home, it will be in {sonar.home}/.sonartmp
File sonarHome = temp.newFolder();
File tmpDir = new File(new File(sonarHome, CoreProperties.GLOBAL_WORKING_DIRECTORY_DEFAULT_VALUE), TempFolderProvider.TMP_NAME);

TempFolder tempFolder = tempFolderProvider.provide(new BootstrapProperties(ImmutableMap.of("sonar.userHome", sonarHome.getAbsolutePath())));
tempFolder.newDir();
tempFolder.newFile();
assertThat(tmpDir).exists();
assertThat(tmpDir.list()).hasSize(2);
}

@Test
public void createTempFolderDefault() throws Exception {
// if nothing is defined, it will be in {user.home}/.sonar/.sonartmp
File defaultSonarHome = new File(System.getProperty("user.home"), ".sonar");
File tmpDir = new File(new File(defaultSonarHome, CoreProperties.GLOBAL_WORKING_DIRECTORY_DEFAULT_VALUE), TempFolderProvider.TMP_NAME);

try {
TempFolder tempFolder = tempFolderProvider.provide(new BootstrapProperties(Collections.<String, String>emptyMap()));
tempFolder.newDir();
tempFolder.newFile();
assertThat(tmpDir).exists();
assertThat(tmpDir.list()).hasSize(2);
} finally {
FileUtils.deleteDirectory(tmpDir);
}
}
}

+ 3
- 23
sonar-batch/src/test/java/org/sonar/batch/duplication/DuplicationCacheTest.java View File

@@ -19,40 +19,20 @@
*/
package org.sonar.batch.duplication;

import org.junit.After;
import org.junit.Before;
import org.sonar.batch.index.AbstractCachesTest;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.batch.sensor.duplication.Duplication;
import org.sonar.api.batch.sensor.duplication.internal.DefaultDuplication;
import org.sonar.batch.index.Caches;
import org.sonar.batch.index.CachesTest;

import static org.assertj.core.api.Assertions.assertThat;

public class DuplicationCacheTest {

@Rule
public TemporaryFolder temp = new TemporaryFolder();
public class DuplicationCacheTest extends AbstractCachesTest {

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

Caches caches;

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

@After
public void stop() {
caches.stop();
}

@Test
public void should_add_clone_groups() {
DuplicationCache cache = new DuplicationCache(caches);

+ 59
- 0
sonar-batch/src/test/java/org/sonar/batch/index/AbstractCachesTest.java View File

@@ -0,0 +1,59 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 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.index;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.rules.TemporaryFolder;

public abstract class AbstractCachesTest {
@ClassRule
public static TemporaryFolder temp = new TemporaryFolder();

protected Caches caches;
protected static CachesManager cachesManager;

@BeforeClass
public static void startClass() {
cachesManager = CachesManagerTest.createCacheOnTemp(temp);
cachesManager.start();
}

@Before
public void start() {
caches = new Caches(cachesManager);
caches.start();
}

@After
public void stop() {
caches.stop();
caches = null;
}

@AfterClass
public static void stopClass() {
cachesManager.stop();
cachesManager = null;
}
}

+ 1
- 21
sonar-batch/src/test/java/org/sonar/batch/index/CacheTest.java View File

@@ -20,32 +20,12 @@
package org.sonar.batch.index;

import com.google.common.collect.Iterables;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonar.batch.index.Cache.Entry;

import static org.assertj.core.api.Assertions.assertThat;

public class CacheTest {

@Rule
public TemporaryFolder temp = new TemporaryFolder();

Caches caches;

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

@After
public void stop() {
caches.stop();
}
public class CacheTest extends AbstractCachesTest {

@Test
public void one_part_key() {

+ 72
- 0
sonar-batch/src/test/java/org/sonar/batch/index/CachesManagerTest.java View File

@@ -0,0 +1,72 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 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.index;

import org.sonar.batch.bootstrap.TempFolderProvider;

import com.google.common.collect.ImmutableMap;
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.BootstrapProperties;

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

import static org.assertj.core.api.Assertions.assertThat;

public class CachesManagerTest {

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

public static CachesManager createCacheOnTemp(TemporaryFolder temp) {
try {
BootstrapProperties bootstrapProps = new BootstrapProperties(ImmutableMap.of(CoreProperties.WORKING_DIRECTORY, temp.newFolder().getAbsolutePath()));
return new CachesManager(new TempFolderProvider().provide(bootstrapProps));
} catch (IOException e) {
throw new RuntimeException(e);
}
}

CachesManager cachesMgr;

@Before
public void prepare() {
cachesMgr = createCacheOnTemp(temp);
cachesMgr.start();
}

@Test
public void should_stop_and_clean_temp_dir() {
File tempDir = cachesMgr.tempDir();
assertThat(tempDir).isDirectory().exists();
assertThat(cachesMgr.persistit()).isNotNull();
assertThat(cachesMgr.persistit().isInitialized()).isTrue();

cachesMgr.stop();

assertThat(tempDir).doesNotExist();
assertThat(cachesMgr.tempDir()).isNull();
assertThat(cachesMgr.persistit()).isNull();
}
}

+ 45
- 55
sonar-batch/src/test/java/org/sonar/batch/index/CachesTest.java View File

@@ -19,73 +19,22 @@
*/
package org.sonar.batch.index;

import com.google.common.collect.ImmutableMap;
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.BootstrapProperties;
import org.sonar.batch.bootstrap.TempFolderProvider;

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

import com.persistit.exception.PersistitException;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;

public class CachesTest {

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

public static Caches createCacheOnTemp(TemporaryFolder temp) {
try {
BootstrapProperties bootstrapProps = new BootstrapProperties(ImmutableMap.of(CoreProperties.WORKING_DIRECTORY, temp.newFolder().getAbsolutePath()));
return new Caches(new TempFolderProvider().provide(bootstrapProps));
} catch (IOException e) {
throw new RuntimeException(e);
}
}

Caches caches;

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

@After
public void stop() {
caches.stop();
}

@Test
public void should_stop_and_clean_temp_dir() {
File tempDir = caches.tempDir();
assertThat(tempDir).isDirectory().exists();
assertThat(caches.persistit()).isNotNull();
assertThat(caches.persistit().isInitialized()).isTrue();

caches.stop();

assertThat(tempDir).doesNotExist();
assertThat(caches.tempDir()).isNull();
assertThat(caches.persistit()).isNull();
}

public class CachesTest extends AbstractCachesTest {
@Test
public void should_create_cache() {
caches.start();
Cache<Element> cache = caches.createCache("foo");
assertThat(cache).isNotNull();
}

@Test
public void should_not_create_cache_twice() {
caches.start();
caches.<Element>createCache("foo");
try {
caches.<Element>createCache("foo");
@@ -95,7 +44,48 @@ public class CachesTest {
}
}

static class Element implements Serializable {
@Test
public void should_clean_resources() throws PersistitException {
Cache<String> c = caches.<String>createCache("test1");
for (int i = 0; i < 1_000_000; i++) {
c.put("a" + i, "a" + i);
}

caches.stop();

// manager continues up
assertThat(cachesManager.persistit().isInitialized()).isTrue();

caches = new Caches(cachesManager);
caches.start();
caches.createCache("test1");
}

@Test
public void leak_test() throws PersistitException {
caches.stop();

System.out.println(cachesManager.tempDir());

int len = 1 * 1024 * 1024;
StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < len; i++) {
sb.append("a");
}

for (int i = 0; i < 3; i++) {
caches = new Caches(cachesManager);
caches.start();
Cache<String> c = caches.<String>createCache("test" + i);
c.put("key" + i, sb.toString());
cachesManager.persistit().flush();

caches.stop();
}
}

private static class Element implements Serializable {
private static final long serialVersionUID = 1L;

}
}

+ 3
- 23
sonar-batch/src/test/java/org/sonar/batch/issue/IssueCacheTest.java View File

@@ -19,19 +19,15 @@
*/
package org.sonar.batch.issue;

import org.sonar.batch.index.AbstractCachesTest;

import com.google.common.base.Function;
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;

@@ -41,23 +37,7 @@ import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

public class IssueCacheTest {

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

Caches caches;

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

@After
public void stop() {
caches.stop();
}
public class IssueCacheTest extends AbstractCachesTest {

@Test
public void should_add_new_issue() {

+ 3
- 25
sonar-batch/src/test/java/org/sonar/batch/issue/tracking/InitialOpenIssuesStackTest.java View File

@@ -20,46 +20,24 @@

package org.sonar.batch.issue.tracking;

import org.sonar.batch.index.AbstractCachesTest;

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.BootstrapProperties;
import org.sonar.batch.bootstrap.TempFolderProvider;
import org.sonar.batch.index.Caches;
import org.sonar.core.issue.db.IssueChangeDto;
import org.sonar.core.issue.db.IssueDto;

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

import static org.assertj.core.api.Assertions.assertThat;

public class InitialOpenIssuesStackTest {

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

public static Caches createCacheOnTemp(TemporaryFolder temp) {
BootstrapProperties bootstrapSettings = new BootstrapProperties(Collections.<String, String>emptyMap());
try {
bootstrapSettings.properties().put(CoreProperties.WORKING_DIRECTORY, temp.newFolder().getAbsolutePath());
} catch (IOException e) {
throw new RuntimeException(e);
}
return new Caches(new TempFolderProvider().provide(bootstrapSettings));
}
public class InitialOpenIssuesStackTest extends AbstractCachesTest {

InitialOpenIssuesStack stack;
Caches caches;

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


+ 73
- 87
sonar-batch/src/test/java/org/sonar/batch/scan/measure/MeasureCacheTest.java View File

@@ -19,13 +19,12 @@
*/
package org.sonar.batch.scan.measure;

import org.sonar.batch.index.AbstractCachesTest;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.batch.measure.MetricFinder;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Measure;
@@ -42,8 +41,6 @@ import org.sonar.api.technicaldebt.batch.Requirement;
import org.sonar.api.technicaldebt.batch.TechnicalDebtModel;
import org.sonar.api.technicaldebt.batch.internal.DefaultCharacteristic;
import org.sonar.batch.index.Cache.Entry;
import org.sonar.batch.index.Caches;
import org.sonar.batch.index.CachesTest;

import java.util.Date;
import java.util.Iterator;
@@ -52,101 +49,90 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class MeasureCacheTest {

@Rule
public TemporaryFolder temp = new TemporaryFolder();

public class MeasureCacheTest extends AbstractCachesTest {
@Rule
public ExpectedException thrown = ExpectedException.none();

Caches caches;

private MetricFinder metricFinder;

private TechnicalDebtModel techDebtModel;

private MeasureCache cache;
private MeasureCache measureCache;

@Before
public void start() {
caches = CachesTest.createCacheOnTemp(temp);
caches.start();
super.start();
metricFinder = mock(MetricFinder.class);
when(metricFinder.findByKey(CoreMetrics.NCLOC_KEY)).thenReturn(CoreMetrics.NCLOC);
techDebtModel = mock(TechnicalDebtModel.class);
cache = new MeasureCache(caches, metricFinder, techDebtModel);
}

@After
public void stop() {
caches.stop();
measureCache = new MeasureCache(caches, metricFinder, techDebtModel);
}

@Test
public void should_add_measure() {
Project p = new Project("struts");

assertThat(cache.entries()).hasSize(0);
assertThat(measureCache.entries()).hasSize(0);

assertThat(cache.byResource(p)).hasSize(0);
assertThat(measureCache.byResource(p)).hasSize(0);

Measure m = new Measure(CoreMetrics.NCLOC, 1.0);
cache.put(p, m);
measureCache.put(p, m);

assertThat(cache.contains(p, m)).isTrue();
assertThat(cache.entries()).hasSize(1);
Iterator<Entry<Measure>> iterator = cache.entries().iterator();
assertThat(measureCache.contains(p, m)).isTrue();
assertThat(measureCache.entries()).hasSize(1);
Iterator<Entry<Measure>> iterator = measureCache.entries().iterator();
iterator.hasNext();
Entry<Measure> next = iterator.next();
assertThat(next.value()).isEqualTo(m);
assertThat(next.key()[0]).isEqualTo("struts");

assertThat(cache.byResource(p)).hasSize(1);
assertThat(cache.byResource(p).iterator().next()).isEqualTo(m);
assertThat(measureCache.byResource(p)).hasSize(1);
assertThat(measureCache.byResource(p).iterator().next()).isEqualTo(m);

Measure mRule = RuleMeasure.createForPriority(CoreMetrics.CRITICAL_VIOLATIONS, RulePriority.BLOCKER, 1.0);
cache.put(p, mRule);
measureCache.put(p, mRule);

assertThat(cache.entries()).hasSize(2);
assertThat(measureCache.entries()).hasSize(2);

assertThat(cache.byResource(p)).hasSize(2);
assertThat(measureCache.byResource(p)).hasSize(2);
}

@Test
public void should_add_measure_with_big_data() {
public void should_add_measure_with_big_data() throws InterruptedException {
Project p = new Project("struts");

assertThat(cache.entries()).hasSize(0);
assertThat(measureCache.entries()).hasSize(0);

assertThat(cache.byResource(p)).hasSize(0);
assertThat(measureCache.byResource(p)).hasSize(0);

Measure m = new Measure(CoreMetrics.NCLOC, 1.0).setDate(new Date());
m.setAlertText("foooooooooooooooooooooooooooooooooooo");
StringBuilder data = new StringBuilder();
for (int i = 0; i < 1048575; i++) {
for (int i = 0; i < 1_048_575; i++) {
data.append("a");
}
m.setData(data.toString());

cache.put(p, m);
measureCache.put(p, m);

assertThat(cache.contains(p, m)).isTrue();
assertThat(cache.entries()).hasSize(1);
Iterator<Entry<Measure>> iterator = cache.entries().iterator();
assertThat(measureCache.contains(p, m)).isTrue();
assertThat(measureCache.entries()).hasSize(1);
Iterator<Entry<Measure>> iterator = measureCache.entries().iterator();
iterator.hasNext();
Entry<Measure> next = iterator.next();
assertThat(next.value()).isEqualTo(m);
assertThat(next.key()[0]).isEqualTo("struts");

assertThat(cache.byResource(p)).hasSize(1);
assertThat(cache.byResource(p).iterator().next()).isEqualTo(m);
assertThat(measureCache.byResource(p)).hasSize(1);
assertThat(measureCache.byResource(p).iterator().next()).isEqualTo(m);

RuleMeasure mRule = RuleMeasure.createForPriority(CoreMetrics.CRITICAL_VIOLATIONS, RulePriority.BLOCKER, 1.0);
mRule.setRuleKey(RuleKey.of("repo", "rule"));
cache.put(p, mRule);
measureCache.put(p, mRule);

assertThat(cache.entries()).hasSize(2);
assertThat(measureCache.entries()).hasSize(2);
}

/**
@@ -156,9 +142,9 @@ public class MeasureCacheTest {
public void should_add_measure_with_too_big_data_for_persistit_pre_patch() {
Project p = new Project("struts");

assertThat(cache.entries()).hasSize(0);
assertThat(measureCache.entries()).hasSize(0);

assertThat(cache.byResource(p)).hasSize(0);
assertThat(measureCache.byResource(p)).hasSize(0);

Measure m = new Measure(CoreMetrics.NCLOC, 1.0).setDate(new Date());
StringBuilder data = new StringBuilder();
@@ -167,33 +153,33 @@ public class MeasureCacheTest {
}
m.setData(data.toString());

cache.put(p, m);
measureCache.put(p, m);

assertThat(cache.contains(p, m)).isTrue();
assertThat(cache.entries()).hasSize(1);
Iterator<Entry<Measure>> iterator = cache.entries().iterator();
assertThat(measureCache.contains(p, m)).isTrue();
assertThat(measureCache.entries()).hasSize(1);
Iterator<Entry<Measure>> iterator = measureCache.entries().iterator();
iterator.hasNext();
Entry<Measure> next = iterator.next();
assertThat(next.value()).isEqualTo(m);
assertThat(next.key()[0]).isEqualTo("struts");

assertThat(cache.byResource(p)).hasSize(1);
assertThat(cache.byResource(p).iterator().next()).isEqualTo(m);
assertThat(measureCache.byResource(p)).hasSize(1);
assertThat(measureCache.byResource(p).iterator().next()).isEqualTo(m);

RuleMeasure mRule = RuleMeasure.createForPriority(CoreMetrics.CRITICAL_VIOLATIONS, RulePriority.BLOCKER, 1.0);
mRule.setRuleKey(RuleKey.of("repo", "rule"));
cache.put(p, mRule);
measureCache.put(p, mRule);

assertThat(cache.entries()).hasSize(2);
assertThat(measureCache.entries()).hasSize(2);
}

@Test
public void should_add_measure_with_too_big_data_for_persistit() {
Project p = new Project("struts");

assertThat(cache.entries()).hasSize(0);
assertThat(measureCache.entries()).hasSize(0);

assertThat(cache.byResource(p)).hasSize(0);
assertThat(measureCache.byResource(p)).hasSize(0);

Measure m = new Measure(CoreMetrics.NCLOC, 1.0).setDate(new Date());
StringBuilder data = new StringBuilder(64 * 1024 * 1024 + 1);
@@ -206,28 +192,28 @@ public class MeasureCacheTest {
thrown.expect(IllegalStateException.class);
thrown.expectMessage("Fail to put element in the cache measures");

cache.put(p, m);
measureCache.put(p, m);
}

@Test
public void should_add_measure_with_same_metric() {
Project p = new Project("struts");

assertThat(cache.entries()).hasSize(0);
assertThat(cache.byResource(p)).hasSize(0);
assertThat(measureCache.entries()).hasSize(0);
assertThat(measureCache.byResource(p)).hasSize(0);

Measure m1 = new Measure(CoreMetrics.NCLOC, 1.0);
Measure m2 = new Measure(CoreMetrics.NCLOC, 1.0).setCharacteristic(new DefaultCharacteristic().setKey("charac"));
Measure m3 = new Measure(CoreMetrics.NCLOC, 1.0).setPersonId(2);
Measure m4 = new RuleMeasure(CoreMetrics.NCLOC, RuleKey.of("repo", "rule"), RulePriority.BLOCKER, null);
cache.put(p, m1);
cache.put(p, m2);
cache.put(p, m3);
cache.put(p, m4);
measureCache.put(p, m1);
measureCache.put(p, m2);
measureCache.put(p, m3);
measureCache.put(p, m4);

assertThat(cache.entries()).hasSize(4);
assertThat(measureCache.entries()).hasSize(4);

assertThat(cache.byResource(p)).hasSize(4);
assertThat(measureCache.byResource(p)).hasSize(4);
}

@Test
@@ -237,36 +223,36 @@ public class MeasureCacheTest {
Resource file1 = Directory.create("foo/bar/File1.txt").setEffectiveKey("struts:foo/bar/File1.txt");
Resource file2 = Directory.create("foo/bar/File2.txt").setEffectiveKey("struts:foo/bar/File2.txt");

assertThat(cache.entries()).hasSize(0);
assertThat(measureCache.entries()).hasSize(0);

assertThat(cache.byResource(p)).hasSize(0);
assertThat(cache.byResource(dir)).hasSize(0);
assertThat(measureCache.byResource(p)).hasSize(0);
assertThat(measureCache.byResource(dir)).hasSize(0);

Measure mFile1 = new Measure(CoreMetrics.NCLOC, 1.0);
cache.put(file1, mFile1);
measureCache.put(file1, mFile1);
Measure mFile2 = new Measure(CoreMetrics.NCLOC, 3.0);
cache.put(file2, mFile2);
measureCache.put(file2, mFile2);

assertThat(cache.entries()).hasSize(2);
assertThat(cache.byResource(p)).hasSize(0);
assertThat(cache.byResource(dir)).hasSize(0);
assertThat(measureCache.entries()).hasSize(2);
assertThat(measureCache.byResource(p)).hasSize(0);
assertThat(measureCache.byResource(dir)).hasSize(0);

Measure mDir = new Measure(CoreMetrics.NCLOC, 4.0);
cache.put(dir, mDir);
measureCache.put(dir, mDir);

assertThat(cache.entries()).hasSize(3);
assertThat(cache.byResource(p)).hasSize(0);
assertThat(cache.byResource(dir)).hasSize(1);
assertThat(cache.byResource(dir).iterator().next()).isEqualTo(mDir);
assertThat(measureCache.entries()).hasSize(3);
assertThat(measureCache.byResource(p)).hasSize(0);
assertThat(measureCache.byResource(dir)).hasSize(1);
assertThat(measureCache.byResource(dir).iterator().next()).isEqualTo(mDir);

Measure mProj = new Measure(CoreMetrics.NCLOC, 4.0);
cache.put(p, mProj);
measureCache.put(p, mProj);

assertThat(cache.entries()).hasSize(4);
assertThat(cache.byResource(p)).hasSize(1);
assertThat(cache.byResource(p).iterator().next()).isEqualTo(mProj);
assertThat(cache.byResource(dir)).hasSize(1);
assertThat(cache.byResource(dir).iterator().next()).isEqualTo(mDir);
assertThat(measureCache.entries()).hasSize(4);
assertThat(measureCache.byResource(p)).hasSize(1);
assertThat(measureCache.byResource(p).iterator().next()).isEqualTo(mProj);
assertThat(measureCache.byResource(dir)).hasSize(1);
assertThat(measureCache.byResource(dir).iterator().next()).isEqualTo(mDir);
}

@Test
@@ -274,9 +260,9 @@ public class MeasureCacheTest {
Resource file1 = File.create("foo/bar/File1.txt").setEffectiveKey("struts:foo/bar/File1.txt");

Measure measure = new Measure(CoreMetrics.NCLOC, 1.786, 5);
cache.put(file1, measure);
measureCache.put(file1, measure);

Measure savedMeasure = cache.byResource(file1).iterator().next();
Measure savedMeasure = measureCache.byResource(file1).iterator().next();

assertThat(EqualsBuilder.reflectionEquals(measure, savedMeasure)).isTrue();

@@ -302,9 +288,9 @@ public class MeasureCacheTest {
measure.setVariation3(13.0);
measure.setVariation4(14.0);
measure.setVariation5(15.0);
cache.put(file1, measure);
measureCache.put(file1, measure);

savedMeasure = cache.byResource(file1).iterator().next();
savedMeasure = measureCache.byResource(file1).iterator().next();
assertThat(EqualsBuilder.reflectionEquals(measure, savedMeasure)).isTrue();

}

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

@@ -467,7 +467,15 @@ public interface CoreProperties {
* @since 4.0
*/
String WORKING_DIRECTORY = "sonar.working.directory";
String WORKING_DIRECTORY_DEFAULT_VALUE = ".sonar";
/**
* @since 5.2
*/
String GLOBAL_WORKING_DIRECTORY = "sonar.globalWorking.directory";
String GLOBAL_WORKING_DIRECTORY_DEFAULT_VALUE = ".";

/**
* @since 3.4

+ 54
- 0
sonar-plugin-api/src/main/java/org/sonar/api/utils/ProjectTempFolder.java View File

@@ -0,0 +1,54 @@
/*
* SonarQube, open source software quality management tool.
* Copyright (C) 2008-2014 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 javax.annotation.Nullable;

import java.io.File;

import org.sonar.api.batch.BatchSide;


/**
* Use this component to deal with temp files/folders that have a scope linked to each
* project analysis.
* Root location will typically be the working directory (see sonar.working.directory)

* @since 5.2
*
*/
@BatchSide
public interface ProjectTempFolder {

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

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

File newFile();

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

}

+ 1
- 1
sonar-plugin-api/src/main/java/org/sonar/api/utils/TempFolder.java View File

@@ -31,7 +31,7 @@ import java.io.File;
* depends on situation:
* <ul>
* <li>${SONAR_HOME}/temp on server side</li>
* <li>Working directory on batch side (see sonar.working.directory)</li>
* <li>${SONAR_HOME}/.sonartmp<rnd> on the batch side</li>
* </ul>
* @since 4.0
*

+ 14
- 1
sonar-plugin-api/src/main/java/org/sonar/api/utils/internal/DefaultTempFolder.java View File

@@ -19,6 +19,7 @@
*/
package org.sonar.api.utils.internal;

import org.sonar.api.utils.ProjectTempFolder;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.utils.TempFolder;
@@ -29,15 +30,21 @@ import java.io.File;
import java.io.IOException;
import java.text.MessageFormat;

public class DefaultTempFolder implements TempFolder {
public class DefaultTempFolder implements TempFolder, ProjectTempFolder {

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

private final File tempDir;
private final boolean cleanUp;

public DefaultTempFolder(File tempDir) {
this(tempDir, false);
}

public DefaultTempFolder(File tempDir, boolean cleanUp) {
this.tempDir = tempDir;
this.cleanUp = cleanUp;
}

@Override
@@ -106,4 +113,10 @@ public class DefaultTempFolder implements TempFolder {
FileUtils.deleteQuietly(tempDir);
}

public void stop() {
if(cleanUp) {
clean();
}
}

}

+ 3
- 1
sonar-plugin-api/src/main/java/org/sonar/api/utils/internal/JUnitTempFolder.java View File

@@ -19,6 +19,8 @@
*/
package org.sonar.api.utils.internal;

import org.sonar.api.utils.ProjectTempFolder;

import org.apache.commons.lang.StringUtils;
import org.junit.rules.ExternalResource;
import org.junit.rules.TemporaryFolder;
@@ -51,7 +53,7 @@ import java.io.IOException;
*
* @since 5.1
*/
public class JUnitTempFolder extends ExternalResource implements TempFolder {
public class JUnitTempFolder extends ExternalResource implements TempFolder, ProjectTempFolder {

private final TemporaryFolder junit = new TemporaryFolder();


Loading…
Cancel
Save