@@ -1091,9 +1091,9 @@ | |||
<version>2.3.1</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.sonarsource</groupId> | |||
<groupId>org.codehaus.sonar</groupId> | |||
<artifactId>sonar-persistit</artifactId> | |||
<version>3.3.2</version> | |||
<version>3.3.1</version> | |||
<exclusions> | |||
<exclusion> | |||
<groupId>commons-logging</groupId> |
@@ -44,4 +44,5 @@ public class TempFolderProvider extends ProviderAdapter { | |||
} | |||
return tempFolder; | |||
} | |||
} |
@@ -25,7 +25,7 @@ | |||
<scope>provided</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.sonarsource</groupId> | |||
<groupId>org.codehaus.sonar</groupId> | |||
<artifactId>sonar-persistit</artifactId> | |||
</dependency> | |||
<dependency> |
@@ -19,16 +19,14 @@ | |||
*/ | |||
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; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.api.utils.UriReader; | |||
import org.sonar.api.utils.internal.TempFolderCleaner; | |||
import org.sonar.batch.components.PastSnapshotFinder; | |||
import org.sonar.batch.deprecated.components.PastSnapshotFinderByDate; | |||
import org.sonar.batch.deprecated.components.PastSnapshotFinderByDays; | |||
@@ -66,14 +64,13 @@ import org.sonar.jpa.session.JpaDatabaseSession; | |||
public class GlobalContainer extends ComponentContainer { | |||
private final Map<String, String> bootstrapProperties; | |||
private PersistentCacheProvider persistentCacheProvider; | |||
private GlobalContainer(Map<String, String> bootstrapProperties) { | |||
super(); | |||
this.bootstrapProperties = bootstrapProperties; | |||
} | |||
public static GlobalContainer create(Map<String, String> bootstrapProperties, List<?> extensions) { | |||
public static GlobalContainer create(Map<String, String> bootstrapProperties, List extensions) { | |||
GlobalContainer container = new GlobalContainer(bootstrapProperties); | |||
container.add(extensions); | |||
return container; | |||
@@ -92,8 +89,6 @@ public class GlobalContainer extends ComponentContainer { | |||
} | |||
private void addBootstrapComponents() { | |||
persistentCacheProvider = new PersistentCacheProvider(); | |||
add( | |||
// plugins | |||
BatchPluginRepository.class, | |||
@@ -103,16 +98,16 @@ public class GlobalContainer extends ComponentContainer { | |||
BatchPluginPredicate.class, | |||
ExtensionInstaller.class, | |||
CachesManager.class, | |||
GlobalSettings.class, | |||
ServerClient.class, | |||
Logback.class, | |||
DefaultServer.class, | |||
new TempFolderProvider(), | |||
TempFolderCleaner.class, | |||
DefaultHttpDownloader.class, | |||
UriReader.class, | |||
new FileCacheProvider(), | |||
persistentCacheProvider, | |||
new PersistentCacheProvider(), | |||
System2.INSTANCE, | |||
DefaultI18n.class, | |||
Durations.class, | |||
@@ -125,7 +120,7 @@ public class GlobalContainer extends ComponentContainer { | |||
addIfMissing(DefaultServerLineHashesLoader.class, ServerLineHashesLoader.class); | |||
} | |||
public void addIfMissing(Object object, Class<?> objectType) { | |||
public void addIfMissing(Object object, Class objectType) { | |||
if (getComponentByType(objectType) == null) { | |||
add(object); | |||
} | |||
@@ -167,7 +162,7 @@ public class GlobalContainer extends ComponentContainer { | |||
public void executeAnalysis(Map<String, String> analysisProperties, Object... components) { | |||
AnalysisProperties props = new AnalysisProperties(analysisProperties, this.getComponentByType(BootstrapProperties.class).property(CoreProperties.ENCRYPTION_SECRET_KEY_PATH)); | |||
persistentCacheProvider.reconfigure(props); | |||
new ProjectScanContainer(this, props, components).execute(); | |||
} | |||
} |
@@ -1,85 +0,0 @@ | |||
/* | |||
* 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.picocontainer.lifecycle.ReflectionLifecycleStrategy; | |||
import org.picocontainer.monitors.NullComponentMonitor; | |||
import org.picocontainer.LifecycleStrategy; | |||
import org.picocontainer.PicoContainer; | |||
import org.picocontainer.ComponentLifecycle; | |||
import org.picocontainer.injectors.ProviderAdapter; | |||
import org.picocontainer.Startable; | |||
public abstract class LifecycleProviderAdapter extends ProviderAdapter implements Startable, ComponentLifecycle<Object> { | |||
private LifecycleStrategy lifecycleStrategy; | |||
protected Object instance; | |||
public LifecycleProviderAdapter() { | |||
this(new ReflectionLifecycleStrategy(new NullComponentMonitor())); | |||
} | |||
public LifecycleProviderAdapter(LifecycleStrategy lifecycleStrategy) { | |||
this.lifecycleStrategy = lifecycleStrategy; | |||
} | |||
@Override | |||
public final void start() { | |||
if (instance != null) { | |||
lifecycleStrategy.start(instance); | |||
} | |||
} | |||
@Override | |||
public final void stop() { | |||
if (instance != null) { | |||
lifecycleStrategy.stop(instance); | |||
} | |||
} | |||
@Override | |||
public void start(PicoContainer container) { | |||
start(); | |||
started = true; | |||
} | |||
@Override | |||
public void stop(PicoContainer container) { | |||
stop(); | |||
started = false; | |||
} | |||
@Override | |||
public void dispose(PicoContainer container) { | |||
} | |||
@Override | |||
public boolean componentHasLifecycle() { | |||
return true; | |||
} | |||
@Override | |||
public boolean isStarted() { | |||
return started; | |||
} | |||
private boolean started = false; | |||
} |
@@ -20,23 +20,27 @@ | |||
package org.sonar.batch.bootstrap; | |||
import org.sonar.home.log.Slf4jLog; | |||
import org.sonar.home.cache.PersistentCacheBuilder; | |||
import org.picocontainer.injectors.ProviderAdapter; | |||
import java.nio.file.Paths; | |||
import java.util.Map; | |||
import org.sonar.home.cache.PersistentCache; | |||
public class PersistentCacheProvider extends ProviderAdapter { | |||
private PersistentCache cache; | |||
public PersistentCache provide(UserProperties props) { | |||
public PersistentCache provide(BootstrapProperties props) { | |||
if (cache == null) { | |||
PersistentCacheBuilder builder = new PersistentCacheBuilder(); | |||
builder.setLog(new Slf4jLog(PersistentCache.class)); | |||
builder.forceUpdate(isForceUpdate(props.properties())); | |||
String enableCache = props.property("sonar.enableHttpCache"); | |||
if (!"true".equals(enableCache)) { | |||
builder.forceUpdate(true); | |||
} | |||
String home = props.property("sonar.userHome"); | |||
if (home != null) { | |||
@@ -47,15 +51,4 @@ public class PersistentCacheProvider extends ProviderAdapter { | |||
} | |||
return cache; | |||
} | |||
public void reconfigure(UserProperties props) { | |||
if (cache != null) { | |||
cache.reconfigure(isForceUpdate(props.properties())); | |||
} | |||
} | |||
private static boolean isForceUpdate(Map<String, String> props) { | |||
String enableCache = props.get("sonar.enableHttpCache"); | |||
return !"true".equals(enableCache); | |||
} | |||
} |
@@ -1,65 +0,0 @@ | |||
/* | |||
* 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.TempFolder; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.sonar.api.CoreProperties; | |||
import org.sonar.api.utils.internal.DefaultTempFolder; | |||
import java.io.IOException; | |||
import java.nio.file.Files; | |||
import java.nio.file.Path; | |||
import java.nio.file.Paths; | |||
public class ProjectTempFolderProvider extends LifecycleProviderAdapter { | |||
static final String TMP_NAME = ".sonartmp"; | |||
private DefaultTempFolder projectTempFolder; | |||
public TempFolder provide(AnalysisProperties props) { | |||
if (projectTempFolder == null) { | |||
String workingDirPath = StringUtils.defaultIfBlank(props.property(CoreProperties.WORKING_DIRECTORY), CoreProperties.WORKING_DIRECTORY_DEFAULT_VALUE); | |||
Path workingDir = Paths.get(workingDirPath).normalize(); | |||
if(!workingDir.isAbsolute()) { | |||
Path base = getBasePath(props); | |||
workingDir = base.resolve(workingDir); | |||
} | |||
Path tempDir = workingDir.resolve(TMP_NAME); | |||
try { | |||
Files.createDirectories(tempDir); | |||
} catch (IOException e) { | |||
throw new IllegalStateException("Unable to create root temp directory " + tempDir, e); | |||
} | |||
projectTempFolder = new DefaultTempFolder(tempDir.toFile(), true); | |||
this.instance = projectTempFolder; | |||
} | |||
return projectTempFolder; | |||
} | |||
private Path getBasePath(AnalysisProperties props) { | |||
String baseDir = props.property("sonar.projectBaseDir"); | |||
if(baseDir == null) { | |||
throw new IllegalStateException("sonar.projectBaseDir needs to be specified"); | |||
} | |||
return Paths.get(baseDir); | |||
} | |||
} |
@@ -19,109 +19,33 @@ | |||
*/ | |||
package org.sonar.batch.bootstrap; | |||
import org.sonar.api.utils.log.Logger; | |||
import org.sonar.api.utils.log.Loggers; | |||
import org.apache.commons.io.FileUtils; | |||
import org.sonar.api.utils.TempFolder; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.picocontainer.injectors.ProviderAdapter; | |||
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.DirectoryStream; | |||
import java.nio.file.Files; | |||
import java.nio.file.Path; | |||
import java.nio.file.Paths; | |||
import java.nio.file.attribute.BasicFileAttributes; | |||
import java.util.concurrent.TimeUnit; | |||
public class TempFolderProvider extends LifecycleProviderAdapter { | |||
private static final Logger LOG = Loggers.get(TempFolderProvider.class); | |||
private static final long CLEAN_MAX_AGE = TimeUnit.DAYS.toMillis(21); | |||
static final String TMP_NAME_PREFIX = ".sonartmp_"; | |||
public class TempFolderProvider extends ProviderAdapter { | |||
private DefaultTempFolder tempFolder; | |||
private TempFolder tempFolder; | |||
public TempFolder provide(BootstrapProperties bootstrapProps) { | |||
if (tempFolder == null) { | |||
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(); | |||
} | |||
try { | |||
cleanTempFolders(workingPath); | |||
} catch (IOException e) { | |||
LOG.warn("failed to clean global working directory: " + e.getMessage()); | |||
} | |||
Path tempDir = workingPath.resolve(TMP_NAME_PREFIX + System.currentTimeMillis()); | |||
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"); | |||
try { | |||
Files.createDirectories(tempDir); | |||
FileUtils.forceMkdir(tempDir); | |||
} catch (IOException e) { | |||
throw new IllegalStateException("Unable to create root temp directory " + tempDir, e); | |||
} | |||
tempFolder = new DefaultTempFolder(tempDir.toFile(), true); | |||
this.instance = tempFolder; | |||
tempFolder = new DefaultTempFolder(tempDir); | |||
} | |||
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"); | |||
} | |||
private static void cleanTempFolders(Path path) throws IOException { | |||
if (Files.exists(path)) { | |||
try (DirectoryStream<Path> stream = Files.newDirectoryStream(path, new CleanFilter())) { | |||
for (Path p : stream) { | |||
FileUtils.deleteQuietly(p.toFile()); | |||
} | |||
} | |||
} | |||
} | |||
private static class CleanFilter implements DirectoryStream.Filter<Path> { | |||
@Override | |||
public boolean accept(Path e) throws IOException { | |||
if (!Files.isDirectory(e)) { | |||
return false; | |||
} | |||
if (!e.getFileName().toString().startsWith(TMP_NAME_PREFIX)) { | |||
return false; | |||
} | |||
long threshold = System.currentTimeMillis() - CLEAN_MAX_AGE; | |||
// we could also check the timestamp in the name, instead | |||
BasicFileAttributes attrs; | |||
try { | |||
attrs = Files.readAttributes(e, BasicFileAttributes.class); | |||
} catch (IOException ioe) { | |||
LOG.warn("couldn't read file attributes for " + e + " : " + ioe.getMessage()); | |||
return false; | |||
} | |||
long creationTime = attrs.creationTime().toMillis(); | |||
return creationTime < threshold; | |||
} | |||
} | |||
} |
@@ -19,9 +19,6 @@ | |||
*/ | |||
package org.sonar.batch.bootstrapper; | |||
import org.sonar.home.log.LogListener; | |||
import org.picocontainer.annotations.Nullable; | |||
import com.google.common.collect.Lists; | |||
import com.google.common.collect.Maps; | |||
import org.sonar.batch.bootstrap.GlobalContainer; | |||
@@ -38,7 +35,7 @@ import java.util.Map; | |||
public final class Batch { | |||
private boolean started = false; | |||
private LoggingConfiguration loggingConfig; | |||
private LoggingConfiguration logging; | |||
private List<Object> components; | |||
private Map<String, String> bootstrapProperties = Maps.newHashMap(); | |||
private GlobalContainer bootstrapContainer; | |||
@@ -53,16 +50,12 @@ public final class Batch { | |||
bootstrapProperties.putAll(builder.bootstrapProperties); | |||
} | |||
if (builder.isEnableLoggingConfiguration()) { | |||
loggingConfig = new LoggingConfiguration(builder.environment).setProperties(bootstrapProperties); | |||
if (builder.listener != null) { | |||
loggingConfig.setListener(builder.listener); | |||
} | |||
logging = LoggingConfiguration.create(builder.environment).setProperties(bootstrapProperties); | |||
} | |||
} | |||
public LoggingConfiguration getLoggingConfiguration() { | |||
return loggingConfig; | |||
return logging; | |||
} | |||
/** | |||
@@ -117,8 +110,8 @@ public final class Batch { | |||
} | |||
private void configureLogging() { | |||
if (loggingConfig != null) { | |||
LoggingConfigurator.apply(loggingConfig); | |||
if (logging != null) { | |||
logging.configure(); | |||
} | |||
} | |||
@@ -131,7 +124,6 @@ public final class Batch { | |||
private EnvironmentInformation environment; | |||
private List<Object> components = Lists.newArrayList(); | |||
private boolean enableLoggingConfiguration = true; | |||
private LogListener listener; | |||
private Builder() { | |||
} | |||
@@ -146,11 +138,6 @@ public final class Batch { | |||
return this; | |||
} | |||
public Builder setLogListener(@Nullable LogListener listener) { | |||
this.listener = listener; | |||
return this; | |||
} | |||
/** | |||
* @deprecated since 3.7 use {@link #setBootstrapProperties(Map)} | |||
*/ |
@@ -1,59 +0,0 @@ | |||
/* | |||
* 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.bootstrapper; | |||
import org.sonar.home.log.LogListener; | |||
import ch.qos.logback.classic.Level; | |||
import ch.qos.logback.core.UnsynchronizedAppenderBase; | |||
import ch.qos.logback.classic.spi.ILoggingEvent; | |||
public class LogCallbackAppender extends UnsynchronizedAppenderBase<ILoggingEvent> { | |||
protected LogListener target; | |||
public LogCallbackAppender(LogListener target) { | |||
setTarget(target); | |||
} | |||
public void setTarget(LogListener target) { | |||
this.target = target; | |||
} | |||
@Override | |||
protected void append(ILoggingEvent event) { | |||
target.log(event.getMessage(), translate(event.getLevel())); | |||
} | |||
private static LogListener.Level translate(Level level) { | |||
switch (level.toInt()) { | |||
case Level.ERROR_INT: | |||
return LogListener.Level.ERROR; | |||
case Level.WARN_INT: | |||
return LogListener.Level.WARN; | |||
case Level.INFO_INT: | |||
return LogListener.Level.INFO; | |||
case Level.DEBUG_INT: | |||
default: | |||
return LogListener.Level.DEBUG; | |||
case Level.TRACE_INT: | |||
return LogListener.Level.TRACE; | |||
} | |||
} | |||
} |
@@ -19,14 +19,14 @@ | |||
*/ | |||
package org.sonar.batch.bootstrapper; | |||
import org.sonar.home.log.LogListener; | |||
import com.google.common.annotations.VisibleForTesting; | |||
import com.google.common.collect.Maps; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.sonar.core.config.Logback; | |||
import javax.annotation.Nullable; | |||
import java.io.File; | |||
import java.util.Map; | |||
/** | |||
@@ -36,25 +36,18 @@ public final class LoggingConfiguration { | |||
public static final String PROPERTY_ROOT_LOGGER_LEVEL = "ROOT_LOGGER_LEVEL"; | |||
public static final String PROPERTY_SQL_LOGGER_LEVEL = "SQL_LOGGER_LEVEL"; | |||
public static final String PROPERTY_FORMAT = "FORMAT"; | |||
public static final String LEVEL_ROOT_VERBOSE = "DEBUG"; | |||
public static final String LEVEL_ROOT_DEFAULT = "INFO"; | |||
public static final String LEVEL_ROOT_DEFAULT = "INFO"; | |||
@VisibleForTesting | |||
static final String FORMAT_DEFAULT = "%d{HH:mm:ss.SSS} %-5level - %msg%n"; | |||
@VisibleForTesting | |||
static final String FORMAT_MAVEN = "[%level] [%d{HH:mm:ss.SSS}] %msg%n"; | |||
Map<String, String> substitutionVariables = Maps.newHashMap(); | |||
LogListener listener = null; | |||
private Map<String, String> substitutionVariables = Maps.newHashMap(); | |||
public LoggingConfiguration() { | |||
this(null); | |||
} | |||
public LoggingConfiguration(@Nullable EnvironmentInformation environment) { | |||
private LoggingConfiguration(@Nullable EnvironmentInformation environment) { | |||
setVerbose(false); | |||
if (environment != null && "maven".equalsIgnoreCase(environment.getKey())) { | |||
setFormat(FORMAT_MAVEN); | |||
@@ -63,29 +56,25 @@ public final class LoggingConfiguration { | |||
} | |||
} | |||
public LoggingConfiguration setProperties(Map<String, String> properties) { | |||
setShowSql(properties); | |||
setVerbose(properties); | |||
return this; | |||
} | |||
public LoggingConfiguration setListener(@Nullable LogListener listener) { | |||
this.listener = listener; | |||
return this; | |||
} | |||
public LoggingConfiguration setVerbose(boolean verbose) { | |||
return setRootLevel(verbose ? LEVEL_ROOT_VERBOSE : LEVEL_ROOT_DEFAULT); | |||
static LoggingConfiguration create(@Nullable EnvironmentInformation environment) { | |||
return new LoggingConfiguration(environment); | |||
} | |||
public LoggingConfiguration setVerbose(Map<String, String> properties) { | |||
public LoggingConfiguration setProperties(Map<String, String> properties) { | |||
String logLevel = properties.get("sonar.log.level"); | |||
String deprecatedProfilingLevel = properties.get("sonar.log.profilingLevel"); | |||
boolean verbose = "true".equals(properties.get("sonar.verbose")) || | |||
"DEBUG".equals(logLevel) || "TRACE".equals(logLevel) || | |||
"BASIC".equals(deprecatedProfilingLevel) || "FULL".equals(deprecatedProfilingLevel); | |||
boolean sql = "TRACE".equals(logLevel) || "FULL".equals(deprecatedProfilingLevel); | |||
return setVerbose(verbose); | |||
setShowSql(sql); | |||
setVerbose(verbose); | |||
return this; | |||
} | |||
public LoggingConfiguration setVerbose(boolean verbose) { | |||
return setRootLevel(verbose ? LEVEL_ROOT_VERBOSE : LEVEL_ROOT_DEFAULT); | |||
} | |||
public LoggingConfiguration setRootLevel(String level) { | |||
@@ -96,14 +85,6 @@ public final class LoggingConfiguration { | |||
return addSubstitutionVariable(PROPERTY_SQL_LOGGER_LEVEL, showSql ? "TRACE" : "WARN"); | |||
} | |||
public LoggingConfiguration setShowSql(Map<String, String> properties) { | |||
String logLevel = properties.get("sonar.log.level"); | |||
String deprecatedProfilingLevel = properties.get("sonar.log.profilingLevel"); | |||
boolean sql = "TRACE".equals(logLevel) || "FULL".equals(deprecatedProfilingLevel); | |||
return setShowSql(sql); | |||
} | |||
@VisibleForTesting | |||
LoggingConfiguration setFormat(String format) { | |||
return addSubstitutionVariable(PROPERTY_FORMAT, StringUtils.defaultIfBlank(format, FORMAT_DEFAULT)); | |||
@@ -114,8 +95,22 @@ public final class LoggingConfiguration { | |||
return this; | |||
} | |||
@VisibleForTesting | |||
String getSubstitutionVariable(String key) { | |||
return substitutionVariables.get(key); | |||
} | |||
LoggingConfiguration configure(String classloaderPath) { | |||
Logback.configure(classloaderPath, substitutionVariables); | |||
return this; | |||
} | |||
LoggingConfiguration configure(File logbackFile) { | |||
Logback.configure(logbackFile, substitutionVariables); | |||
return this; | |||
} | |||
LoggingConfiguration configure() { | |||
Logback.configure("/org/sonar/batch/bootstrapper/logback.xml", substitutionVariables); | |||
return this; | |||
} | |||
} |
@@ -1,77 +0,0 @@ | |||
/* | |||
* 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.bootstrapper; | |||
import org.sonar.home.log.LogListener; | |||
import ch.qos.logback.core.Appender; | |||
import ch.qos.logback.classic.Level; | |||
import org.apache.commons.lang.StringUtils; | |||
import java.io.File; | |||
import ch.qos.logback.classic.Logger; | |||
import ch.qos.logback.classic.spi.ILoggingEvent; | |||
import org.slf4j.LoggerFactory; | |||
import org.sonar.core.config.Logback; | |||
public class LoggingConfigurator { | |||
private LoggingConfigurator() { | |||
} | |||
public static void apply(LoggingConfiguration conf, File logbackFile) { | |||
Logback.configure(logbackFile, conf.substitutionVariables); | |||
if (conf.listener != null) { | |||
setCustomRootAppender(conf); | |||
} | |||
} | |||
public static void apply(LoggingConfiguration conf) { | |||
apply(conf, "/org/sonar/batch/bootstrapper/logback.xml"); | |||
} | |||
public static void apply(LoggingConfiguration conf, String classloaderPath) { | |||
Logback.configure(classloaderPath, conf.substitutionVariables); | |||
// if not set, keep default behavior (configured to stdout through the file in classpath) | |||
if (conf.listener != null) { | |||
setCustomRootAppender(conf); | |||
} | |||
} | |||
private static void setCustomRootAppender(LoggingConfiguration conf) { | |||
Logger logger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); | |||
String pattern = StringUtils.defaultIfBlank(conf.substitutionVariables.get(LoggingConfiguration.PROPERTY_FORMAT), LoggingConfiguration.FORMAT_DEFAULT); | |||
String level = StringUtils.defaultIfBlank(conf.substitutionVariables.get(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL), LoggingConfiguration.LEVEL_ROOT_DEFAULT); | |||
logger.detachAndStopAllAppenders(); | |||
logger.addAppender(createAppender(pattern, conf.listener)); | |||
logger.setLevel(Level.toLevel(level)); | |||
} | |||
private static Appender<ILoggingEvent> createAppender(String pattern, LogListener target) { | |||
LogCallbackAppender appender = new LogCallbackAppender(target); | |||
appender.setName("custom_stream"); | |||
appender.start(); | |||
return appender; | |||
} | |||
} |
@@ -19,44 +19,64 @@ | |||
*/ | |||
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.Volume; | |||
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 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 Map<String, Exchange> cacheMap = Maps.newHashMap(); | |||
private final Set<String> cacheNames = Sets.newHashSet(); | |||
private File tempDir; | |||
private Persistit persistit; | |||
private Volume volume; | |||
private final TempFolder tempFolder; | |||
public Caches(CachesManager caches) { | |||
persistit = caches.persistit(); | |||
doStart(); | |||
} | |||
@Override | |||
public void start() { | |||
// done in constructor | |||
public Caches(TempFolder tempFolder) { | |||
this.tempFolder = tempFolder; | |||
initPersistit(); | |||
} | |||
private void doStart() { | |||
private void initPersistit() { | |||
try { | |||
persistit.flush(); | |||
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(); | |||
volume = persistit.createTemporaryVolume(); | |||
} catch (Exception e) { | |||
throw new IllegalStateException("Fail to create a cache volume", e); | |||
throw new IllegalStateException("Fail to start caches", e); | |||
} | |||
} | |||
@@ -67,12 +87,12 @@ public class Caches implements Startable { | |||
public <V> Cache<V> createCache(String cacheName) { | |||
Preconditions.checkState(volume != null && volume.isOpened(), "Caches are not initialized"); | |||
Preconditions.checkState(!cacheMap.containsKey(cacheName), "Cache is already created: " + cacheName); | |||
Preconditions.checkState(!cacheNames.contains(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); | |||
cacheMap.put(cacheName, exchange); | |||
cacheNames.add(cacheName); | |||
return cache; | |||
} catch (Exception e) { | |||
throw new IllegalStateException("Fail to create cache: " + cacheName, e); | |||
@@ -80,21 +100,31 @@ public class Caches implements Startable { | |||
} | |||
@Override | |||
public void stop() { | |||
for (Entry<String, Exchange> e : cacheMap.entrySet()) { | |||
persistit.releaseExchange(e.getValue()); | |||
} | |||
cacheMap.clear(); | |||
public void start() { | |||
// already started in constructor | |||
} | |||
if (volume != null) { | |||
@Override | |||
public void stop() { | |||
if (persistit != null) { | |||
try { | |||
volume.close(); | |||
volume.delete(); | |||
persistit.close(false); | |||
persistit = null; | |||
volume = null; | |||
} 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; | |||
} | |||
} |
@@ -1,98 +0,0 @@ | |||
/* | |||
* 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,8 +19,6 @@ | |||
*/ | |||
package org.sonar.batch.mediumtest; | |||
import org.sonar.home.log.LogListener; | |||
import com.google.common.base.Function; | |||
import com.google.common.io.Files; | |||
import org.sonar.api.CoreProperties; | |||
@@ -80,16 +78,10 @@ public class BatchMediumTester { | |||
private final FakeServerIssuesLoader serverIssues = new FakeServerIssuesLoader(); | |||
private final FakeServerLineHashesLoader serverLineHashes = new FakeServerLineHashesLoader(); | |||
private final Map<String, String> bootstrapProperties = new HashMap<>(); | |||
private LogListener logListener = null; | |||
public BatchMediumTester build() { | |||
return new BatchMediumTester(this); | |||
} | |||
public BatchMediumTesterBuilder setLogListener(LogListener listener) { | |||
this.logListener = listener; | |||
return this; | |||
} | |||
public BatchMediumTesterBuilder registerPlugin(String pluginKey, File location) { | |||
pluginInstaller.add(pluginKey, location); | |||
@@ -175,7 +167,6 @@ public class BatchMediumTester { | |||
builder.serverLineHashes, | |||
new DefaultDebtModel()) | |||
.setBootstrapProperties(builder.bootstrapProperties) | |||
.setLogListener(builder.logListener) | |||
.build(); | |||
} | |||
@@ -19,8 +19,6 @@ | |||
*/ | |||
package org.sonar.batch.scan; | |||
import org.sonar.batch.bootstrap.ProjectTempFolderProvider; | |||
import com.google.common.annotations.VisibleForTesting; | |||
import org.sonar.api.CoreProperties; | |||
import org.sonar.api.batch.InstantiationStrategy; | |||
@@ -153,10 +151,7 @@ public class ProjectScanContainer extends ComponentContainer { | |||
Caches.class, | |||
BatchComponentCache.class, | |||
// temp | |||
new ProjectTempFolderProvider(), | |||
// file system | |||
// file system | |||
InputPathCache.class, | |||
PathResolver.class, | |||
@@ -1,79 +0,0 @@ | |||
/* | |||
* 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 static org.assertj.core.api.Assertions.assertThat; | |||
import org.junit.Before; | |||
import org.picocontainer.Startable; | |||
import org.junit.Test; | |||
public class LifecycleProviderAdapterTest { | |||
private DummyProvider provider; | |||
@Before | |||
public void setUp() { | |||
provider = new DummyProvider(); | |||
provider.provide(); | |||
} | |||
@Test | |||
public void testStart() { | |||
// ComponentLifecycle's start gets called on the provider | |||
provider.start(null); | |||
assertThat(provider.inst.started).isEqualTo(true); | |||
assertThat(provider.isStarted()).isEqualTo(true); | |||
assertThat(provider.inst.stopped).isEqualTo(false); | |||
} | |||
@Test | |||
public void testSop() { | |||
// ComponentLifecycle's stop gets called on the provider | |||
provider.stop(null); | |||
assertThat(provider.inst.stopped).isEqualTo(true); | |||
assertThat(provider.isStarted()).isEqualTo(false); | |||
assertThat(provider.inst.started).isEqualTo(false); | |||
} | |||
public class DummyProvided implements Startable { | |||
boolean started = false; | |||
boolean stopped = false; | |||
@Override | |||
public void start() { | |||
started = true; | |||
} | |||
@Override | |||
public void stop() { | |||
stopped = true; | |||
} | |||
} | |||
public class DummyProvider extends LifecycleProviderAdapter { | |||
DummyProvided inst; | |||
public DummyProvided provide() { | |||
inst = new DummyProvided(); | |||
super.instance = inst; | |||
return inst; | |||
} | |||
} | |||
} |
@@ -19,20 +19,24 @@ | |||
*/ | |||
package org.sonar.batch.bootstrap; | |||
import java.util.Collections; | |||
import org.mockito.Mock; | |||
import org.mockito.MockitoAnnotations; | |||
import org.junit.Before; | |||
import static org.mockito.Mockito.when; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import org.junit.Test; | |||
public class PersistentCacheProviderTest { | |||
private PersistentCacheProvider provider = null; | |||
@Mock | |||
private BootstrapProperties props = null; | |||
@Before | |||
public void prepare() { | |||
props = new BootstrapProperties(Collections.<String, String>emptyMap()); | |||
MockitoAnnotations.initMocks(this); | |||
provider = new PersistentCacheProvider(); | |||
} | |||
@@ -51,7 +55,7 @@ public class PersistentCacheProviderTest { | |||
// normally force update (cache disabled) | |||
assertThat(provider.provide(props).isForceUpdate()).isTrue(); | |||
props.properties().put("sonar.enableHttpCache", "true"); | |||
when(props.property("sonar.enableHttpCache")).thenReturn("true"); | |||
provider = new PersistentCacheProvider(); | |||
assertThat(provider.provide(props).isForceUpdate()).isFalse(); | |||
} |
@@ -1,71 +0,0 @@ | |||
/* | |||
* 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.TempFolder; | |||
import org.apache.commons.io.FileUtils; | |||
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); | |||
TempFolder tempFolder = tempFolderProvider.provide(new AnalysisProperties(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 workingDir = temp.newFolder(); | |||
File defaultDir = new File(new File(workingDir, CoreProperties.WORKING_DIRECTORY_DEFAULT_VALUE), ProjectTempFolderProvider.TMP_NAME); | |||
try { | |||
TempFolder tempFolder = tempFolderProvider.provide(new AnalysisProperties(ImmutableMap.of("sonar.projectBaseDir", workingDir.getAbsolutePath()), "")); | |||
tempFolder.newDir(); | |||
tempFolder.newFile(); | |||
assertThat(defaultDir).exists(); | |||
assertThat(defaultDir.list()).hasSize(2); | |||
} finally { | |||
FileUtils.deleteDirectory(defaultDir); | |||
} | |||
} | |||
} |
@@ -19,98 +19,34 @@ | |||
*/ | |||
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.io.IOException; | |||
import java.nio.file.Files; | |||
import java.nio.file.attribute.BasicFileAttributeView; | |||
import java.nio.file.attribute.FileTime; | |||
import java.util.Collections; | |||
import java.util.concurrent.TimeUnit; | |||
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 TemporaryFolder temp = new TemporaryFolder(); | |||
private TempFolderProvider tempFolderProvider = new TempFolderProvider(); | |||
@Test | |||
public void createTempFolderProps() throws Exception { | |||
File workingDir = temp.getRoot(); | |||
TempFolder tempFolder = tempFolderProvider.provide(new BootstrapProperties(ImmutableMap.of(CoreProperties.GLOBAL_WORKING_DIRECTORY, workingDir.getAbsolutePath()))); | |||
tempFolder.newDir(); | |||
tempFolder.newFile(); | |||
assertThat(getCreatedTempDir(workingDir)).exists(); | |||
assertThat(getCreatedTempDir(workingDir).list()).hasSize(2); | |||
} | |||
@Test | |||
public void cleanUpOld() throws IOException { | |||
long creationTime = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(100); | |||
File workingDir = temp.getRoot(); | |||
for (int i = 0; i < 3; i++) { | |||
File tmp = new File(workingDir, ".sonartmp_" + i); | |||
tmp.mkdirs(); | |||
setFileCreationDate(tmp, creationTime); | |||
} | |||
@Rule | |||
public ExpectedException throwable = ExpectedException.none(); | |||
tempFolderProvider.provide(new BootstrapProperties(ImmutableMap.of(CoreProperties.GLOBAL_WORKING_DIRECTORY, workingDir.getAbsolutePath()))); | |||
// this also checks that all other temps were deleted | |||
assertThat(getCreatedTempDir(workingDir)).exists(); | |||
} | |||
@Rule | |||
public TemporaryFolder temp = new TemporaryFolder(); | |||
@Test | |||
public void createTempFolderSonarHome() throws Exception { | |||
// with sonar home, it will be in {sonar.home}/.sonartmp | |||
File sonarHome = temp.getRoot(); | |||
File workingDir = new File(sonarHome, CoreProperties.GLOBAL_WORKING_DIRECTORY_DEFAULT_VALUE); | |||
TempFolder tempFolder = tempFolderProvider.provide(new BootstrapProperties(ImmutableMap.of("sonar.userHome", sonarHome.getAbsolutePath()))); | |||
public void createTempFolder() throws Exception { | |||
File workingDir = temp.newFolder(); | |||
TempFolderProvider tempFolderProvider = new TempFolderProvider(); | |||
TempFolder tempFolder = tempFolderProvider.provide(new BootstrapProperties(ImmutableMap.of(CoreProperties.WORKING_DIRECTORY, workingDir.getAbsolutePath()))); | |||
tempFolder.newDir(); | |||
tempFolder.newFile(); | |||
assertThat(getCreatedTempDir(workingDir)).exists(); | |||
assertThat(getCreatedTempDir(workingDir).list()).hasSize(2); | |||
} | |||
@Test | |||
public void createTempFolderDefault() throws Exception { | |||
File userHome = temp.getRoot(); | |||
System.setProperty("user.home", userHome.getAbsolutePath()); | |||
// if nothing is defined, it will be in {user.home}/.sonar/.sonartmp | |||
File defaultSonarHome = new File(System.getProperty("user.home"), ".sonar"); | |||
File workingDir = new File(defaultSonarHome, CoreProperties.GLOBAL_WORKING_DIRECTORY_DEFAULT_VALUE).getAbsoluteFile(); | |||
try { | |||
TempFolder tempFolder = tempFolderProvider.provide(new BootstrapProperties(Collections.<String, String>emptyMap())); | |||
tempFolder.newDir(); | |||
tempFolder.newFile(); | |||
assertThat(getCreatedTempDir(workingDir)).exists(); | |||
assertThat(getCreatedTempDir(workingDir).list()).hasSize(2); | |||
} finally { | |||
FileUtils.deleteDirectory(getCreatedTempDir(workingDir)); | |||
} | |||
} | |||
private File getCreatedTempDir(File workingDir) { | |||
assertThat(workingDir.listFiles()).hasSize(1); | |||
return workingDir.listFiles()[0]; | |||
} | |||
private void setFileCreationDate(File f, long time) throws IOException { | |||
BasicFileAttributeView attributes = Files.getFileAttributeView(f.toPath(), BasicFileAttributeView.class); | |||
FileTime creationTime = FileTime.fromMillis(time); | |||
attributes.setTimes(creationTime, creationTime, creationTime); | |||
assertThat(new File(workingDir, ".sonartmp")).exists(); | |||
assertThat(new File(workingDir, ".sonartmp").list()).hasSize(2); | |||
} | |||
} |
@@ -19,12 +19,8 @@ | |||
*/ | |||
package org.sonar.batch.bootstrapper; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
import org.sonar.home.log.LogListener; | |||
import org.junit.Test; | |||
import static org.junit.Assert.assertNotNull; | |||
import static org.junit.Assert.assertNull; | |||
@@ -65,11 +61,4 @@ public class BatchTest { | |||
public void loggingConfigurationShouldBeEnabledByDefault() { | |||
assertNotNull(newBatch().getLoggingConfiguration()); | |||
} | |||
@Test | |||
public void shoudSetLogListener() { | |||
LogListener listener = mock(LogListener.class); | |||
Batch batch = Batch.builder().setLogListener(listener).build(); | |||
assertThat(batch.getLoggingConfiguration().listener).isEqualTo(listener); | |||
} | |||
} |
@@ -1,66 +0,0 @@ | |||
/* | |||
* 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.bootstrapper; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.when; | |||
import static org.mockito.Mockito.verify; | |||
import static org.mockito.Mockito.verifyNoMoreInteractions; | |||
import ch.qos.logback.classic.Level; | |||
import ch.qos.logback.classic.spi.ILoggingEvent; | |||
import org.junit.Test; | |||
import org.sonar.home.log.LogListener; | |||
import org.junit.Before; | |||
public class LogCallbackAppenderTest { | |||
private LogListener listener; | |||
private LogCallbackAppender appender; | |||
private ILoggingEvent event; | |||
@Before | |||
public void setUp() { | |||
listener = mock(LogListener.class); | |||
appender = new LogCallbackAppender(listener); | |||
event = mock(ILoggingEvent.class); | |||
when(event.getMessage()).thenReturn("test"); | |||
when(event.getLevel()).thenReturn(Level.INFO); | |||
} | |||
@Test | |||
public void testAppendLog() { | |||
appender.append(event); | |||
verify(event).getMessage(); | |||
verify(event).getLevel(); | |||
verify(listener).log("test", LogListener.Level.INFO); | |||
verifyNoMoreInteractions(event, listener); | |||
} | |||
@Test | |||
public void testChangeTarget() { | |||
listener = mock(LogListener.class); | |||
appender.setTarget(listener); | |||
testAppendLog(); | |||
} | |||
} |
@@ -19,67 +19,58 @@ | |||
*/ | |||
package org.sonar.batch.bootstrapper; | |||
import org.sonar.home.log.LogListener; | |||
import com.google.common.collect.Maps; | |||
import org.junit.Test; | |||
import java.util.Map; | |||
import static org.mockito.Mockito.mock; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
public class LoggingConfigurationTest { | |||
@Test | |||
public void testSetVerbose() { | |||
assertThat(new LoggingConfiguration(null).setVerbose(true) | |||
assertThat(LoggingConfiguration.create(null).setVerbose(true) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo(LoggingConfiguration.LEVEL_ROOT_VERBOSE); | |||
assertThat(new LoggingConfiguration(null).setVerbose(false) | |||
assertThat(LoggingConfiguration.create(null).setVerbose(false) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo(LoggingConfiguration.LEVEL_ROOT_DEFAULT); | |||
assertThat(new LoggingConfiguration(null).setRootLevel("ERROR") | |||
assertThat(LoggingConfiguration.create(null).setRootLevel("ERROR") | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo("ERROR"); | |||
} | |||
@Test | |||
public void shouldNotBeVerboseByDefault() { | |||
assertThat(new LoggingConfiguration(null) | |||
assertThat(LoggingConfiguration.create(null) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo(LoggingConfiguration.LEVEL_ROOT_DEFAULT); | |||
} | |||
@Test | |||
public void test_log_listener_setter() { | |||
LogListener listener = mock(LogListener.class); | |||
assertThat(new LoggingConfiguration(null).setListener(listener).listener).isEqualTo(listener); | |||
} | |||
@Test | |||
public void test_deprecated_log_properties() { | |||
Map<String, String> properties = Maps.newHashMap(); | |||
assertThat(new LoggingConfiguration(null).setProperties(properties) | |||
assertThat(LoggingConfiguration.create(null).setProperties(properties) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo(LoggingConfiguration.LEVEL_ROOT_DEFAULT); | |||
properties.put("sonar.verbose", "true"); | |||
LoggingConfiguration conf = new LoggingConfiguration(null).setProperties(properties); | |||
LoggingConfiguration conf = LoggingConfiguration.create(null).setProperties(properties); | |||
assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo(LoggingConfiguration.LEVEL_ROOT_VERBOSE); | |||
assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL)).isEqualTo("WARN"); | |||
properties.put("sonar.verbose", "false"); | |||
conf = new LoggingConfiguration(null).setProperties(properties); | |||
conf = LoggingConfiguration.create(null).setProperties(properties); | |||
assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo(LoggingConfiguration.LEVEL_ROOT_DEFAULT); | |||
assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL)).isEqualTo("WARN"); | |||
properties.put("sonar.verbose", "false"); | |||
properties.put("sonar.log.profilingLevel", "FULL"); | |||
conf = new LoggingConfiguration(null).setProperties(properties); | |||
conf = LoggingConfiguration.create(null).setProperties(properties); | |||
assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo("DEBUG"); | |||
assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL)).isEqualTo("TRACE"); | |||
properties.put("sonar.verbose", "false"); | |||
properties.put("sonar.log.profilingLevel", "BASIC"); | |||
conf = new LoggingConfiguration(null).setProperties(properties); | |||
conf = LoggingConfiguration.create(null).setProperties(properties); | |||
assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo("DEBUG"); | |||
assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL)).isEqualTo("WARN"); | |||
} | |||
@@ -87,53 +78,53 @@ public class LoggingConfigurationTest { | |||
@Test | |||
public void test_log_level_property() { | |||
Map<String, String> properties = Maps.newHashMap(); | |||
LoggingConfiguration conf = new LoggingConfiguration(null).setProperties(properties); | |||
LoggingConfiguration conf = LoggingConfiguration.create(null).setProperties(properties); | |||
assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo("INFO"); | |||
assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL)).isEqualTo("WARN"); | |||
properties.put("sonar.log.level", "INFO"); | |||
conf = new LoggingConfiguration(null).setProperties(properties); | |||
conf = LoggingConfiguration.create(null).setProperties(properties); | |||
assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo("INFO"); | |||
assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL)).isEqualTo("WARN"); | |||
properties.put("sonar.log.level", "DEBUG"); | |||
conf = new LoggingConfiguration(null).setProperties(properties); | |||
conf = LoggingConfiguration.create(null).setProperties(properties); | |||
assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo("DEBUG"); | |||
assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL)).isEqualTo("WARN"); | |||
properties.put("sonar.log.level", "TRACE"); | |||
conf = new LoggingConfiguration(null).setProperties(properties); | |||
conf = LoggingConfiguration.create(null).setProperties(properties); | |||
assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_ROOT_LOGGER_LEVEL)).isEqualTo("DEBUG"); | |||
assertThat(conf.getSubstitutionVariable(LoggingConfiguration.PROPERTY_SQL_LOGGER_LEVEL)).isEqualTo("TRACE"); | |||
} | |||
@Test | |||
public void testDefaultFormat() { | |||
assertThat(new LoggingConfiguration(null) | |||
assertThat(LoggingConfiguration.create(null) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_FORMAT)).isEqualTo(LoggingConfiguration.FORMAT_DEFAULT); | |||
} | |||
@Test | |||
public void testMavenFormat() { | |||
assertThat(new LoggingConfiguration(new EnvironmentInformation("maven", "1.0")) | |||
assertThat(LoggingConfiguration.create(new EnvironmentInformation("maven", "1.0")) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_FORMAT)).isEqualTo(LoggingConfiguration.FORMAT_MAVEN); | |||
} | |||
@Test | |||
public void testSetFormat() { | |||
assertThat(new LoggingConfiguration(null).setFormat("%d %level") | |||
assertThat(LoggingConfiguration.create(null).setFormat("%d %level") | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_FORMAT)).isEqualTo("%d %level"); | |||
} | |||
@Test | |||
public void shouldNotSetBlankFormat() { | |||
assertThat(new LoggingConfiguration(null).setFormat(null) | |||
assertThat(LoggingConfiguration.create(null).setFormat(null) | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_FORMAT)).isEqualTo(LoggingConfiguration.FORMAT_DEFAULT); | |||
assertThat(new LoggingConfiguration(null).setFormat("") | |||
assertThat(LoggingConfiguration.create(null).setFormat("") | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_FORMAT)).isEqualTo(LoggingConfiguration.FORMAT_DEFAULT); | |||
assertThat(new LoggingConfiguration(null).setFormat(" ") | |||
assertThat(LoggingConfiguration.create(null).setFormat(" ") | |||
.getSubstitutionVariable(LoggingConfiguration.PROPERTY_FORMAT)).isEqualTo(LoggingConfiguration.FORMAT_DEFAULT); | |||
} | |||
} |
@@ -1,139 +0,0 @@ | |||
/* | |||
* 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.bootstrapper; | |||
import org.sonar.home.log.LogListener; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import java.io.ByteArrayOutputStream; | |||
import java.io.PrintStream; | |||
import java.io.UnsupportedEncodingException; | |||
import java.nio.charset.StandardCharsets; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import org.junit.Test; | |||
import org.junit.Before; | |||
public class LoggingConfiguratorTest { | |||
private static final String TEST_STR = "foo"; | |||
private LoggingConfiguration conf = new LoggingConfiguration(); | |||
private ByteArrayOutputStream out; | |||
private SimpleLogListener listener; | |||
@Before | |||
public void setUp() { | |||
out = new ByteArrayOutputStream(); | |||
conf = new LoggingConfiguration(); | |||
listener = new SimpleLogListener(); | |||
} | |||
private class SimpleLogListener implements LogListener { | |||
String msg; | |||
Level level; | |||
@Override | |||
public void log(String msg, Level level) { | |||
this.msg = msg; | |||
this.level = level; | |||
} | |||
} | |||
@Test | |||
public void testCustomAppender() throws UnsupportedEncodingException { | |||
conf.setListener(listener); | |||
LoggingConfigurator.apply(conf); | |||
Logger logger = LoggerFactory.getLogger(this.getClass()); | |||
logger.info(TEST_STR); | |||
assertThat(listener.msg).endsWith(TEST_STR); | |||
assertThat(listener.level).isEqualTo(LogListener.Level.INFO); | |||
} | |||
@Test | |||
public void testNoStdout() throws UnsupportedEncodingException { | |||
System.setOut(new PrintStream(out, false, StandardCharsets.UTF_8.name())); | |||
conf.setListener(listener); | |||
LoggingConfigurator.apply(conf); | |||
Logger logger = LoggerFactory.getLogger(this.getClass()); | |||
logger.error(TEST_STR); | |||
logger.info(TEST_STR); | |||
logger.debug(TEST_STR); | |||
assertThat(out.size()).isEqualTo(0); | |||
} | |||
@Test | |||
public void testFormatNoEffect() throws UnsupportedEncodingException { | |||
conf.setListener(listener); | |||
conf.setFormat("%t"); | |||
LoggingConfigurator.apply(conf); | |||
Logger logger = LoggerFactory.getLogger(this.getClass()); | |||
logger.info("info"); | |||
assertThat(listener.msg).isEqualTo("info"); | |||
} | |||
@Test | |||
public void testSqlClasspath() throws UnsupportedEncodingException { | |||
String classpath = "/org/sonar/batch/bootstrapper/logback.xml"; | |||
conf.setListener(listener); | |||
conf.setShowSql(true); | |||
LoggingConfigurator.apply(conf, classpath); | |||
Logger logger = LoggerFactory.getLogger("java.sql"); | |||
logger.info("foo"); | |||
assertThat(listener.msg).endsWith(TEST_STR); | |||
} | |||
@Test | |||
public void testNoListener() throws UnsupportedEncodingException { | |||
System.setOut(new PrintStream(out, false, StandardCharsets.UTF_8.name())); | |||
LoggingConfigurator.apply(conf); | |||
Logger logger = LoggerFactory.getLogger(this.getClass()); | |||
logger.info("info"); | |||
assertThat(new String(out.toByteArray(), StandardCharsets.UTF_8)).contains("info"); | |||
} | |||
@Test | |||
public void testNoSqlClasspath() throws UnsupportedEncodingException { | |||
String classpath = "/org/sonar/batch/bootstrapper/logback.xml"; | |||
conf.setListener(listener); | |||
conf.setShowSql(false); | |||
LoggingConfigurator.apply(conf, classpath); | |||
Logger logger = LoggerFactory.getLogger("java.sql"); | |||
logger.info("foo"); | |||
assertThat(listener.msg).isNull(); | |||
} | |||
} |
@@ -19,20 +19,40 @@ | |||
*/ | |||
package org.sonar.batch.duplication; | |||
import org.sonar.batch.index.AbstractCachesTest; | |||
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.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 extends AbstractCachesTest { | |||
public class DuplicationCacheTest { | |||
@Rule | |||
public TemporaryFolder temp = new TemporaryFolder(); | |||
@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); |
@@ -1,59 +0,0 @@ | |||
/* | |||
* 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,12 +20,32 @@ | |||
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 extends AbstractCachesTest { | |||
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(); | |||
} | |||
@Test | |||
public void one_part_key() { |
@@ -1,72 +0,0 @@ | |||
/* | |||
* 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,71 +19,83 @@ | |||
*/ | |||
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 extends AbstractCachesTest { | |||
@Test | |||
public void should_create_cache() { | |||
Cache<Element> cache = caches.createCache("foo"); | |||
assertThat(cache).isNotNull(); | |||
} | |||
public class CachesTest { | |||
@Test | |||
public void should_not_create_cache_twice() { | |||
caches.<Element>createCache("foo"); | |||
@ClassRule | |||
public static TemporaryFolder temp = new TemporaryFolder(); | |||
public static Caches createCacheOnTemp(TemporaryFolder temp) { | |||
try { | |||
caches.<Element>createCache("foo"); | |||
fail(); | |||
} catch (IllegalStateException e) { | |||
// ok | |||
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); | |||
} | |||
} | |||
@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 caches; | |||
caches.stop(); | |||
// manager continues up | |||
assertThat(cachesManager.persistit().isInitialized()).isTrue(); | |||
@Before | |||
public void prepare() { | |||
caches = createCacheOnTemp(temp); | |||
} | |||
caches = new Caches(cachesManager); | |||
caches.start(); | |||
caches.createCache("test1"); | |||
@After | |||
public void stop() { | |||
caches.stop(); | |||
} | |||
@Test | |||
public void leak_test() throws PersistitException { | |||
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(); | |||
int len = 1 * 1024 * 1024; | |||
StringBuilder sb = new StringBuilder(len); | |||
for (int i = 0; i < len; i++) { | |||
sb.append("a"); | |||
} | |||
assertThat(tempDir).doesNotExist(); | |||
assertThat(caches.tempDir()).isNull(); | |||
assertThat(caches.persistit()).isNull(); | |||
} | |||
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(); | |||
@Test | |||
public void should_create_cache() { | |||
caches.start(); | |||
Cache<Element> cache = caches.createCache("foo"); | |||
assertThat(cache).isNotNull(); | |||
} | |||
caches.stop(); | |||
@Test | |||
public void should_not_create_cache_twice() { | |||
caches.start(); | |||
caches.<Element>createCache("foo"); | |||
try { | |||
caches.<Element>createCache("foo"); | |||
fail(); | |||
} catch (IllegalStateException e) { | |||
// ok | |||
} | |||
} | |||
private static class Element implements Serializable { | |||
private static final long serialVersionUID = 1L; | |||
static class Element implements Serializable { | |||
} | |||
} |
@@ -19,15 +19,19 @@ | |||
*/ | |||
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; | |||
@@ -37,7 +41,23 @@ import java.util.List; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
public class IssueCacheTest extends AbstractCachesTest { | |||
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(); | |||
} | |||
@Test | |||
public void should_add_new_issue() { |
@@ -20,24 +20,46 @@ | |||
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 extends AbstractCachesTest { | |||
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)); | |||
} | |||
InitialOpenIssuesStack stack; | |||
Caches caches; | |||
@Before | |||
public void before() { | |||
caches = createCacheOnTemp(temp); | |||
caches.start(); | |||
stack = new InitialOpenIssuesStack(caches); | |||
} | |||
@@ -1,187 +0,0 @@ | |||
/* | |||
* 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.mediumtest.log; | |||
import org.junit.BeforeClass; | |||
import org.junit.AfterClass; | |||
import org.sonar.home.log.LogListener; | |||
import org.sonar.home.log.LogListener.Level; | |||
import org.apache.commons.io.FileUtils; | |||
import org.junit.Test; | |||
import com.google.common.collect.ImmutableMap; | |||
import org.junit.After; | |||
import org.junit.Before; | |||
import org.sonar.batch.mediumtest.BatchMediumTester; | |||
import org.sonar.xoo.XooPlugin; | |||
import java.io.ByteArrayOutputStream; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.io.PrintStream; | |||
import java.util.LinkedList; | |||
import java.util.List; | |||
import java.util.regex.Matcher; | |||
import java.util.regex.Pattern; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import org.junit.Rule; | |||
import org.junit.rules.ExpectedException; | |||
import org.junit.rules.TemporaryFolder; | |||
public class LogListenerTest { | |||
@Rule | |||
public TemporaryFolder temp = new TemporaryFolder(); | |||
@Rule | |||
public ExpectedException thrown = ExpectedException.none(); | |||
private Pattern simpleTimePattern = Pattern.compile("\\d{2}:\\d{2}:\\d{2}"); | |||
private List<LogEvent> logOutput; | |||
private ByteArrayOutputStream stdOutTarget = new ByteArrayOutputStream(); | |||
private ByteArrayOutputStream stdErrTarget = new ByteArrayOutputStream(); | |||
private static PrintStream savedStdOut; | |||
private static PrintStream savedStdErr; | |||
public BatchMediumTester tester = BatchMediumTester.builder() | |||
.registerPlugin("xoo", new XooPlugin()) | |||
.addDefaultQProfile("xoo", "Sonar Way") | |||
.setLogListener(new SimpleLogListener()) | |||
.build(); | |||
private File baseDir; | |||
private ImmutableMap.Builder<String, String> builder; | |||
@BeforeClass | |||
public static void backupStdStreams() { | |||
savedStdOut = System.out; | |||
savedStdErr = System.err; | |||
} | |||
@AfterClass | |||
public static void resumeStdStreams() { | |||
if (savedStdOut != null) { | |||
System.setOut(savedStdOut); | |||
} | |||
if (savedStdErr != null) { | |||
System.setErr(savedStdErr); | |||
} | |||
} | |||
@Before | |||
public void prepare() throws IOException { | |||
System.setOut(new PrintStream(stdOutTarget)); | |||
System.setErr(new PrintStream(stdErrTarget)); | |||
logOutput = new LinkedList<>(); | |||
tester.start(); | |||
baseDir = temp.newFolder(); | |||
builder = ImmutableMap.<String, String>builder() | |||
.put("sonar.task", "scan") | |||
.put("sonar.projectBaseDir", baseDir.getAbsolutePath()) | |||
.put("sonar.projectKey", "com.foo.project") | |||
.put("sonar.projectName", "Foo Project") | |||
.put("sonar.projectVersion", "1.0-SNAPSHOT") | |||
.put("sonar.projectDescription", "Description of Foo Project"); | |||
} | |||
private void assertNoStdOutput() { | |||
assertThat(stdOutTarget.toByteArray()).isEmpty(); | |||
assertThat(stdErrTarget.toByteArray()).isEmpty(); | |||
} | |||
/** | |||
* Check that log message is not formatted, i.e. has no log level and timestamp. | |||
*/ | |||
private void assertMsgClean(String msg) { | |||
for (Level l : Level.values()) { | |||
assertThat(msg).doesNotContain(l.toString()); | |||
} | |||
Matcher matcher = simpleTimePattern.matcher(msg); | |||
assertThat(matcher.find()).isFalse(); | |||
} | |||
@After | |||
public void stop() { | |||
tester.stop(); | |||
} | |||
@Test | |||
public void testNoStdLog() throws IOException { | |||
File srcDir = new File(baseDir, "src"); | |||
srcDir.mkdir(); | |||
File xooFile = new File(srcDir, "sample.xoo"); | |||
FileUtils.write(xooFile, "Sample xoo\ncontent"); | |||
tester.newTask() | |||
.properties(builder | |||
.put("sonar.sources", "src") | |||
.build()) | |||
.start(); | |||
assertNoStdOutput(); | |||
assertThat(logOutput).isNotEmpty(); | |||
for (LogEvent e : logOutput) { | |||
savedStdOut.println("[captured]" + e.level + " " + e.msg); | |||
} | |||
} | |||
@Test | |||
public void testNoFormattedMsgs() throws IOException { | |||
File srcDir = new File(baseDir, "src"); | |||
srcDir.mkdir(); | |||
File xooFile = new File(srcDir, "sample.xoo"); | |||
FileUtils.write(xooFile, "Sample xoo\ncontent"); | |||
tester.newTask() | |||
.properties(builder | |||
.put("sonar.sources", "src") | |||
.build()) | |||
.start(); | |||
assertNoStdOutput(); | |||
for (LogEvent e : logOutput) { | |||
assertMsgClean(e.msg); | |||
savedStdOut.println("[captured]" + e.level + " " + e.msg); | |||
} | |||
} | |||
private class SimpleLogListener implements LogListener { | |||
@Override | |||
public void log(String msg, Level level) { | |||
logOutput.add(new LogEvent(msg, level)); | |||
} | |||
} | |||
private static class LogEvent { | |||
String msg; | |||
Level level; | |||
LogEvent(String msg, Level level) { | |||
this.msg = msg; | |||
this.level = level; | |||
} | |||
} | |||
} |
@@ -19,12 +19,13 @@ | |||
*/ | |||
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; | |||
@@ -41,6 +42,8 @@ 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; | |||
@@ -49,90 +52,101 @@ import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.when; | |||
public class MeasureCacheTest extends AbstractCachesTest { | |||
public class MeasureCacheTest { | |||
@Rule | |||
public TemporaryFolder temp = new TemporaryFolder(); | |||
@Rule | |||
public ExpectedException thrown = ExpectedException.none(); | |||
Caches caches; | |||
private MetricFinder metricFinder; | |||
private TechnicalDebtModel techDebtModel; | |||
private MeasureCache measureCache; | |||
private MeasureCache cache; | |||
@Before | |||
public void start() { | |||
super.start(); | |||
caches = CachesTest.createCacheOnTemp(temp); | |||
caches.start(); | |||
metricFinder = mock(MetricFinder.class); | |||
when(metricFinder.findByKey(CoreMetrics.NCLOC_KEY)).thenReturn(CoreMetrics.NCLOC); | |||
techDebtModel = mock(TechnicalDebtModel.class); | |||
measureCache = new MeasureCache(caches, metricFinder, techDebtModel); | |||
cache = new MeasureCache(caches, metricFinder, techDebtModel); | |||
} | |||
@After | |||
public void stop() { | |||
caches.stop(); | |||
} | |||
@Test | |||
public void should_add_measure() { | |||
Project p = new Project("struts"); | |||
assertThat(measureCache.entries()).hasSize(0); | |||
assertThat(cache.entries()).hasSize(0); | |||
assertThat(measureCache.byResource(p)).hasSize(0); | |||
assertThat(cache.byResource(p)).hasSize(0); | |||
Measure m = new Measure(CoreMetrics.NCLOC, 1.0); | |||
measureCache.put(p, m); | |||
cache.put(p, m); | |||
assertThat(measureCache.contains(p, m)).isTrue(); | |||
assertThat(measureCache.entries()).hasSize(1); | |||
Iterator<Entry<Measure>> iterator = measureCache.entries().iterator(); | |||
assertThat(cache.contains(p, m)).isTrue(); | |||
assertThat(cache.entries()).hasSize(1); | |||
Iterator<Entry<Measure>> iterator = cache.entries().iterator(); | |||
iterator.hasNext(); | |||
Entry<Measure> next = iterator.next(); | |||
assertThat(next.value()).isEqualTo(m); | |||
assertThat(next.key()[0]).isEqualTo("struts"); | |||
assertThat(measureCache.byResource(p)).hasSize(1); | |||
assertThat(measureCache.byResource(p).iterator().next()).isEqualTo(m); | |||
assertThat(cache.byResource(p)).hasSize(1); | |||
assertThat(cache.byResource(p).iterator().next()).isEqualTo(m); | |||
Measure mRule = RuleMeasure.createForPriority(CoreMetrics.CRITICAL_VIOLATIONS, RulePriority.BLOCKER, 1.0); | |||
measureCache.put(p, mRule); | |||
cache.put(p, mRule); | |||
assertThat(measureCache.entries()).hasSize(2); | |||
assertThat(cache.entries()).hasSize(2); | |||
assertThat(measureCache.byResource(p)).hasSize(2); | |||
assertThat(cache.byResource(p)).hasSize(2); | |||
} | |||
@Test | |||
public void should_add_measure_with_big_data() throws InterruptedException { | |||
public void should_add_measure_with_big_data() { | |||
Project p = new Project("struts"); | |||
assertThat(measureCache.entries()).hasSize(0); | |||
assertThat(cache.entries()).hasSize(0); | |||
assertThat(measureCache.byResource(p)).hasSize(0); | |||
assertThat(cache.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 < 1_048_575; i++) { | |||
for (int i = 0; i < 1048575; i++) { | |||
data.append("a"); | |||
} | |||
m.setData(data.toString()); | |||
measureCache.put(p, m); | |||
cache.put(p, m); | |||
assertThat(measureCache.contains(p, m)).isTrue(); | |||
assertThat(measureCache.entries()).hasSize(1); | |||
Iterator<Entry<Measure>> iterator = measureCache.entries().iterator(); | |||
assertThat(cache.contains(p, m)).isTrue(); | |||
assertThat(cache.entries()).hasSize(1); | |||
Iterator<Entry<Measure>> iterator = cache.entries().iterator(); | |||
iterator.hasNext(); | |||
Entry<Measure> next = iterator.next(); | |||
assertThat(next.value()).isEqualTo(m); | |||
assertThat(next.key()[0]).isEqualTo("struts"); | |||
assertThat(measureCache.byResource(p)).hasSize(1); | |||
assertThat(measureCache.byResource(p).iterator().next()).isEqualTo(m); | |||
assertThat(cache.byResource(p)).hasSize(1); | |||
assertThat(cache.byResource(p).iterator().next()).isEqualTo(m); | |||
RuleMeasure mRule = RuleMeasure.createForPriority(CoreMetrics.CRITICAL_VIOLATIONS, RulePriority.BLOCKER, 1.0); | |||
mRule.setRuleKey(RuleKey.of("repo", "rule")); | |||
measureCache.put(p, mRule); | |||
cache.put(p, mRule); | |||
assertThat(measureCache.entries()).hasSize(2); | |||
assertThat(cache.entries()).hasSize(2); | |||
} | |||
/** | |||
@@ -142,9 +156,9 @@ public class MeasureCacheTest extends AbstractCachesTest { | |||
public void should_add_measure_with_too_big_data_for_persistit_pre_patch() { | |||
Project p = new Project("struts"); | |||
assertThat(measureCache.entries()).hasSize(0); | |||
assertThat(cache.entries()).hasSize(0); | |||
assertThat(measureCache.byResource(p)).hasSize(0); | |||
assertThat(cache.byResource(p)).hasSize(0); | |||
Measure m = new Measure(CoreMetrics.NCLOC, 1.0).setDate(new Date()); | |||
StringBuilder data = new StringBuilder(); | |||
@@ -153,33 +167,33 @@ public class MeasureCacheTest extends AbstractCachesTest { | |||
} | |||
m.setData(data.toString()); | |||
measureCache.put(p, m); | |||
cache.put(p, m); | |||
assertThat(measureCache.contains(p, m)).isTrue(); | |||
assertThat(measureCache.entries()).hasSize(1); | |||
Iterator<Entry<Measure>> iterator = measureCache.entries().iterator(); | |||
assertThat(cache.contains(p, m)).isTrue(); | |||
assertThat(cache.entries()).hasSize(1); | |||
Iterator<Entry<Measure>> iterator = cache.entries().iterator(); | |||
iterator.hasNext(); | |||
Entry<Measure> next = iterator.next(); | |||
assertThat(next.value()).isEqualTo(m); | |||
assertThat(next.key()[0]).isEqualTo("struts"); | |||
assertThat(measureCache.byResource(p)).hasSize(1); | |||
assertThat(measureCache.byResource(p).iterator().next()).isEqualTo(m); | |||
assertThat(cache.byResource(p)).hasSize(1); | |||
assertThat(cache.byResource(p).iterator().next()).isEqualTo(m); | |||
RuleMeasure mRule = RuleMeasure.createForPriority(CoreMetrics.CRITICAL_VIOLATIONS, RulePriority.BLOCKER, 1.0); | |||
mRule.setRuleKey(RuleKey.of("repo", "rule")); | |||
measureCache.put(p, mRule); | |||
cache.put(p, mRule); | |||
assertThat(measureCache.entries()).hasSize(2); | |||
assertThat(cache.entries()).hasSize(2); | |||
} | |||
@Test | |||
public void should_add_measure_with_too_big_data_for_persistit() { | |||
Project p = new Project("struts"); | |||
assertThat(measureCache.entries()).hasSize(0); | |||
assertThat(cache.entries()).hasSize(0); | |||
assertThat(measureCache.byResource(p)).hasSize(0); | |||
assertThat(cache.byResource(p)).hasSize(0); | |||
Measure m = new Measure(CoreMetrics.NCLOC, 1.0).setDate(new Date()); | |||
StringBuilder data = new StringBuilder(64 * 1024 * 1024 + 1); | |||
@@ -192,28 +206,28 @@ public class MeasureCacheTest extends AbstractCachesTest { | |||
thrown.expect(IllegalStateException.class); | |||
thrown.expectMessage("Fail to put element in the cache measures"); | |||
measureCache.put(p, m); | |||
cache.put(p, m); | |||
} | |||
@Test | |||
public void should_add_measure_with_same_metric() { | |||
Project p = new Project("struts"); | |||
assertThat(measureCache.entries()).hasSize(0); | |||
assertThat(measureCache.byResource(p)).hasSize(0); | |||
assertThat(cache.entries()).hasSize(0); | |||
assertThat(cache.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); | |||
measureCache.put(p, m1); | |||
measureCache.put(p, m2); | |||
measureCache.put(p, m3); | |||
measureCache.put(p, m4); | |||
cache.put(p, m1); | |||
cache.put(p, m2); | |||
cache.put(p, m3); | |||
cache.put(p, m4); | |||
assertThat(measureCache.entries()).hasSize(4); | |||
assertThat(cache.entries()).hasSize(4); | |||
assertThat(measureCache.byResource(p)).hasSize(4); | |||
assertThat(cache.byResource(p)).hasSize(4); | |||
} | |||
@Test | |||
@@ -223,36 +237,36 @@ public class MeasureCacheTest extends AbstractCachesTest { | |||
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(measureCache.entries()).hasSize(0); | |||
assertThat(cache.entries()).hasSize(0); | |||
assertThat(measureCache.byResource(p)).hasSize(0); | |||
assertThat(measureCache.byResource(dir)).hasSize(0); | |||
assertThat(cache.byResource(p)).hasSize(0); | |||
assertThat(cache.byResource(dir)).hasSize(0); | |||
Measure mFile1 = new Measure(CoreMetrics.NCLOC, 1.0); | |||
measureCache.put(file1, mFile1); | |||
cache.put(file1, mFile1); | |||
Measure mFile2 = new Measure(CoreMetrics.NCLOC, 3.0); | |||
measureCache.put(file2, mFile2); | |||
cache.put(file2, mFile2); | |||
assertThat(measureCache.entries()).hasSize(2); | |||
assertThat(measureCache.byResource(p)).hasSize(0); | |||
assertThat(measureCache.byResource(dir)).hasSize(0); | |||
assertThat(cache.entries()).hasSize(2); | |||
assertThat(cache.byResource(p)).hasSize(0); | |||
assertThat(cache.byResource(dir)).hasSize(0); | |||
Measure mDir = new Measure(CoreMetrics.NCLOC, 4.0); | |||
measureCache.put(dir, mDir); | |||
cache.put(dir, 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); | |||
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); | |||
Measure mProj = new Measure(CoreMetrics.NCLOC, 4.0); | |||
measureCache.put(p, mProj); | |||
cache.put(p, mProj); | |||
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); | |||
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); | |||
} | |||
@Test | |||
@@ -260,9 +274,9 @@ public class MeasureCacheTest extends AbstractCachesTest { | |||
Resource file1 = File.create("foo/bar/File1.txt").setEffectiveKey("struts:foo/bar/File1.txt"); | |||
Measure measure = new Measure(CoreMetrics.NCLOC, 1.786, 5); | |||
measureCache.put(file1, measure); | |||
cache.put(file1, measure); | |||
Measure savedMeasure = measureCache.byResource(file1).iterator().next(); | |||
Measure savedMeasure = cache.byResource(file1).iterator().next(); | |||
assertThat(EqualsBuilder.reflectionEquals(measure, savedMeasure)).isTrue(); | |||
@@ -288,9 +302,9 @@ public class MeasureCacheTest extends AbstractCachesTest { | |||
measure.setVariation3(13.0); | |||
measure.setVariation4(14.0); | |||
measure.setVariation5(15.0); | |||
measureCache.put(file1, measure); | |||
cache.put(file1, measure); | |||
savedMeasure = measureCache.byResource(file1).iterator().next(); | |||
savedMeasure = cache.byResource(file1).iterator().next(); | |||
assertThat(EqualsBuilder.reflectionEquals(measure, savedMeasure)).isTrue(); | |||
} |
@@ -52,19 +52,15 @@ public class PersistentCache { | |||
// eviction strategy is to expire entries after modification once a time duration has elapsed | |||
private final long defaultDurationToExpireMs; | |||
private final Log log; | |||
private boolean forceUpdate; | |||
private final boolean forceUpdate; | |||
public PersistentCache(Path baseDir, long defaultDurationToExpireMs, Log log, boolean forceUpdate) { | |||
this.baseDir = baseDir; | |||
this.defaultDurationToExpireMs = defaultDurationToExpireMs; | |||
this.log = log; | |||
this.forceUpdate = forceUpdate; | |||
reconfigure(forceUpdate); | |||
log.info("cache: " + baseDir + ", default expiration time (ms): " + defaultDurationToExpireMs); | |||
} | |||
public void reconfigure(boolean forceUpdate) { | |||
this.forceUpdate = forceUpdate; | |||
if (forceUpdate) { | |||
log.debug("cache: forcing update"); |
@@ -30,19 +30,17 @@ import java.nio.file.Paths; | |||
import java.util.concurrent.TimeUnit; | |||
public class PersistentCacheBuilder { | |||
private static final long DEFAULT_EXPIRE_DURATION = TimeUnit.MILLISECONDS.convert(1L, TimeUnit.DAYS); | |||
private static final String DIR_NAME = "ws_cache"; | |||
private boolean forceUpdate = false; | |||
private Path cachePath = null; | |||
private Log log = new StandardLog(); | |||
private String name = "ws_cache"; | |||
public PersistentCache build() { | |||
if (cachePath == null) { | |||
setSonarHome(findHome()); | |||
} | |||
return new PersistentCache(cachePath, DEFAULT_EXPIRE_DURATION, log, forceUpdate); | |||
return new PersistentCache(cachePath, TimeUnit.MILLISECONDS.convert(1L, TimeUnit.DAYS), log, forceUpdate); | |||
} | |||
public PersistentCacheBuilder setLog(Log log) { | |||
@@ -52,7 +50,7 @@ public class PersistentCacheBuilder { | |||
public PersistentCacheBuilder setSonarHome(@Nullable Path p) { | |||
if (p != null) { | |||
this.cachePath = p.resolve(DIR_NAME); | |||
this.cachePath = p.resolve(name); | |||
} | |||
return this; | |||
} |
@@ -1,28 +0,0 @@ | |||
/* | |||
* 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.home.log; | |||
public interface LogListener { | |||
void log(String msg, Level level); | |||
enum Level { | |||
ERROR, WARN, INFO, DEBUG, TRACE; | |||
} | |||
} |
@@ -19,13 +19,12 @@ | |||
*/ | |||
package org.sonar.home.cache; | |||
import org.apache.commons.io.FileUtils; | |||
import org.sonar.home.log.Slf4jLog; | |||
import org.junit.Rule; | |||
import org.junit.rules.TemporaryFolder; | |||
import java.io.File; | |||
import java.nio.file.Path; | |||
import java.util.concurrent.Callable; | |||
import static org.mockito.Mockito.when; | |||
@@ -96,26 +95,9 @@ public class PersistentCacheTest { | |||
assertCacheHit(true); | |||
} | |||
@Test | |||
public void testReconfigure() throws Exception { | |||
cache = new PersistentCache(tmp.getRoot().toPath(), Long.MAX_VALUE, log, true); | |||
assertCacheHit(false); | |||
assertCacheHit(false); | |||
File root = tmp.getRoot(); | |||
FileUtils.deleteQuietly(root); | |||
// should re-create cache directory and start using the cache | |||
cache.reconfigure(false); | |||
assertThat(root).exists(); | |||
assertCacheHit(false); | |||
assertCacheHit(true); | |||
} | |||
@Test | |||
public void testExpiration() throws Exception { | |||
// negative time to make sure it is expired on the second call | |||
//negative time to make sure it is expired on the second call | |||
cache = new PersistentCache(tmp.getRoot().toPath(), -100, log, false); | |||
assertCacheHit(false); | |||
assertCacheHit(false); | |||
@@ -136,7 +118,7 @@ public class PersistentCacheTest { | |||
return VALUE; | |||
} | |||
} | |||
/** | |||
* WSCache should be transparent regarding exceptions: if an exception is thrown by the value loader, it should pass through | |||
* the cache to the original caller using the cache. |
@@ -467,15 +467,7 @@ 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 |
@@ -31,7 +31,7 @@ import java.io.File; | |||
* depends on situation: | |||
* <ul> | |||
* <li>${SONAR_HOME}/temp on server side</li> | |||
* <li>${SONAR_HOME}/.sonartmp<rnd> on the batch side</li> | |||
* <li>Working directory on batch side (see sonar.working.directory)</li> | |||
* </ul> | |||
* @since 4.0 | |||
* |
@@ -35,15 +35,9 @@ public class DefaultTempFolder implements TempFolder { | |||
private static final int TEMP_DIR_ATTEMPTS = 10000; | |||
private final File tempDir; | |||
private final boolean deleteOnExit; | |||
public DefaultTempFolder(File tempDir) { | |||
this(tempDir, false); | |||
} | |||
public DefaultTempFolder(File tempDir, boolean deleteOnExit) { | |||
this.tempDir = tempDir; | |||
this.deleteOnExit = deleteOnExit; | |||
} | |||
@Override | |||
@@ -112,10 +106,4 @@ public class DefaultTempFolder implements TempFolder { | |||
FileUtils.deleteQuietly(tempDir); | |||
} | |||
public void stop() { | |||
if (deleteOnExit) { | |||
clean(); | |||
} | |||
} | |||
} |
@@ -19,9 +19,11 @@ | |||
*/ | |||
package org.sonar.api.utils.internal; | |||
import org.sonar.api.batch.BatchSide; | |||
import org.sonar.api.server.ServerSide; | |||
import org.sonar.api.utils.TempFolder; | |||
@BatchSide | |||
@ServerSide | |||
public class TempFolderCleaner { | |||