@@ -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> |
@@ -44,5 +44,4 @@ public class TempFolderProvider extends ProviderAdapter { | |||
} | |||
return tempFolder; | |||
} | |||
} |
@@ -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, |
@@ -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; | |||
} | |||
} |
@@ -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"); | |||
} | |||
} |
@@ -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); |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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, | |||
@@ -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); | |||
} | |||
} | |||
} |
@@ -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); | |||
} | |||
} | |||
} |
@@ -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); |
@@ -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; | |||
} | |||
} |
@@ -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() { |
@@ -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(); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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() { |
@@ -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); | |||
} | |||
@@ -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(); | |||
} |
@@ -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 |
@@ -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); | |||
} |
@@ -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 | |||
* |
@@ -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(); | |||
} | |||
} | |||
} |
@@ -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(); | |||