diff options
author | simonbrandhof <simon.brandhof@gmail.com> | 2010-09-06 14:08:06 +0000 |
---|---|---|
committer | simonbrandhof <simon.brandhof@gmail.com> | 2010-09-06 14:08:06 +0000 |
commit | aeadc1f9129274949daaa57738c7c4550bdfbc7b (patch) | |
tree | 08dadf5ef7474fc41d1d48f74648f1ba8b55f34d /sonar-batch | |
download | sonarqube-aeadc1f9129274949daaa57738c7c4550bdfbc7b.tar.gz sonarqube-aeadc1f9129274949daaa57738c7c4550bdfbc7b.zip |
SONAR-236 remove deprecated code from checkstyle plugin + display default value of rule parameters in Q profile console
Diffstat (limited to 'sonar-batch')
119 files changed, 6948 insertions, 0 deletions
diff --git a/sonar-batch/pom.xml b/sonar-batch/pom.xml new file mode 100644 index 00000000000..5ff838014a5 --- /dev/null +++ b/sonar-batch/pom.xml @@ -0,0 +1,61 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.codehaus.sonar</groupId> + <artifactId>sonar</artifactId> + <version>2.3-SNAPSHOT</version> + </parent> + + <groupId>org.codehaus.sonar</groupId> + <artifactId>sonar-batch</artifactId> + <packaging>jar</packaging> + <name>Sonar :: Batch</name> + + <dependencies> + <dependency> + <groupId>org.codehaus.sonar</groupId> + <artifactId>sonar-core</artifactId> + </dependency> + <dependency> + <groupId>org.codehaus.sonar</groupId> + <artifactId>sonar-deprecated</artifactId> + </dependency> + <dependency> + <groupId>org.codehaus.sonar</groupId> + <artifactId>sonar-plugin-api</artifactId> + </dependency> + <dependency> + <groupId>org.codehaus.sonar</groupId> + <artifactId>sonar-squid</artifactId> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-core</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + </dependency> + <dependency> + <groupId>org.codehaus.sonar</groupId> + <artifactId>sonar-testing-harness</artifactId> + <scope>test</scope> + </dependency> + </dependencies> +</project>
\ No newline at end of file diff --git a/sonar-batch/src/main/java/org/sonar/batch/Batch.java b/sonar-batch/src/main/java/org/sonar/batch/Batch.java new file mode 100644 index 00000000000..cf199af94be --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/Batch.java @@ -0,0 +1,114 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.apache.commons.configuration.Configuration; +import org.picocontainer.Characteristics; +import org.picocontainer.MutablePicoContainer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.Plugins; +import org.sonar.api.resources.Project; +import org.sonar.api.utils.HttpDownloader; +import org.sonar.api.utils.IocContainer; +import org.sonar.api.utils.ServerHttpClient; +import org.sonar.batch.indexer.DefaultSonarIndex; +import org.sonar.core.plugin.JpaPluginDao; +import org.sonar.jpa.session.DatabaseSessionProvider; +import org.sonar.jpa.session.DriverDatabaseConnector; +import org.sonar.jpa.session.ThreadLocalDatabaseSessionFactory; + +import java.net.URLClassLoader; + +public class Batch { + + private static final Logger LOG = LoggerFactory.getLogger(Batch.class); + + private Configuration configuration; + private Object[] components; + + public Batch(Configuration configuration, Object... components) { + this.configuration = configuration; + this.components = components; + } + + public void execute() { + MutablePicoContainer container = null; + try { + container = buildPicoContainer(); + container.start(); + analyzeProjects(container); + + } finally { + if (container != null) { + container.stop(); + } + } + } + + private void analyzeProjects(MutablePicoContainer container) { + // a child container is built to ensure database connector is up + MutablePicoContainer batchContainer = container.makeChildContainer(); + batchContainer.as(Characteristics.CACHE).addComponent(ServerMetadata.class); + batchContainer.as(Characteristics.CACHE).addComponent(ProjectTree.class); + batchContainer.as(Characteristics.CACHE).addComponent(DefaultSonarIndex.class); + batchContainer.as(Characteristics.CACHE).addComponent(JpaPluginDao.class); + batchContainer.as(Characteristics.CACHE).addComponent(BatchPluginRepository.class); + batchContainer.as(Characteristics.CACHE).addComponent(Plugins.class); + batchContainer.as(Characteristics.CACHE).addComponent(ServerHttpClient.class); + batchContainer.as(Characteristics.CACHE).addComponent(HttpDownloader.class); + batchContainer.start(); + + ProjectTree projectTree = batchContainer.getComponent(ProjectTree.class); + DefaultSonarIndex index = batchContainer.getComponent(DefaultSonarIndex.class); + analyzeProject(batchContainer, index, projectTree.getRootProject()); + + // batchContainer is stopped by its parent + } + + private MutablePicoContainer buildPicoContainer() { + MutablePicoContainer container = IocContainer.buildPicoContainer(); + + register(container, configuration); + URLClassLoader fullClassloader = RemoteClassLoader.createForJdbcDriver(configuration).getClassLoader(); + // set as the current context classloader for hibernate, else it does not find the JDBC driver. + Thread.currentThread().setContextClassLoader(fullClassloader); + + register(container, new DriverDatabaseConnector(configuration, fullClassloader)); + register(container, ThreadLocalDatabaseSessionFactory.class); + container.as(Characteristics.CACHE).addAdapter(new DatabaseSessionProvider()); + for (Object component : components) { + register(container, component); + } + return container; + } + + private void register(MutablePicoContainer container, Object component) { + container.as(Characteristics.CACHE).addComponent(component); + } + + private void analyzeProject(MutablePicoContainer container, DefaultSonarIndex index, Project project) { + for (Project module : project.getModules()) { + analyzeProject(container, index, module); + } + LOG.info("------------- Analyzing " + project.getName()); + new ProjectBatch(container).execute(index, project); + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/BatchPluginRepository.java b/sonar-batch/src/main/java/org/sonar/batch/BatchPluginRepository.java new file mode 100644 index 00000000000..105686834e4 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/BatchPluginRepository.java @@ -0,0 +1,95 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import com.google.common.collect.HashMultimap; +import org.picocontainer.MutablePicoContainer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.BatchExtension; +import org.sonar.api.Plugin; +import org.sonar.api.platform.PluginRepository; +import org.sonar.core.plugin.JpaPlugin; +import org.sonar.core.plugin.JpaPluginDao; +import org.sonar.core.plugin.JpaPluginFile; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +public class BatchPluginRepository extends PluginRepository { + + private Map<String, ClassLoader> classloaders; + private String baseUrl; + private JpaPluginDao dao; + + public BatchPluginRepository(JpaPluginDao dao, ServerMetadata server) { + this.dao= dao; + this.baseUrl = server.getUrl() + "/deploy/plugins/"; + } + + public void start() { + HashMultimap<String, URL> urlsByKey = HashMultimap.create(); + for (JpaPluginFile pluginFile : dao.getPluginFiles()) { + try { + String key = getClassloaderKey(pluginFile.getPluginKey()); + URL url = new URL(baseUrl + pluginFile.getPath()); + urlsByKey.put(key, url); + + } catch (MalformedURLException e) { + throw new RuntimeException("Can not build the classloader of the plugin " + pluginFile.getPluginKey(), e); + } + } + + classloaders = new HashMap<String, ClassLoader>(); + for (String key : urlsByKey.keySet()) { + Set<URL> urls = urlsByKey.get(key); + + Logger logger = LoggerFactory.getLogger(getClass()); + if (logger.isDebugEnabled()) { + logger.debug("Classloader of plugin " + key + ":"); + for (URL url : urls) { + logger.debug(" -> " + url); + } + } + classloaders.put(key, new RemoteClassLoader(urls, Thread.currentThread().getContextClassLoader()).getClassLoader()); + } + } + + private String getClassloaderKey(String pluginKey) { + return "sonar-plugin-" + pluginKey; + } + + public void registerPlugins(MutablePicoContainer pico) { + try { + for (JpaPlugin pluginMetadata : dao.getPlugins()) { + String classloaderKey = getClassloaderKey(pluginMetadata.getKey()); + Class claz = classloaders.get(classloaderKey).loadClass(pluginMetadata.getPluginClass()); + Plugin plugin = (Plugin) claz.newInstance(); + registerPlugin(pico, plugin, BatchExtension.class); + } + + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/CheckProfileProvider.java b/sonar-batch/src/main/java/org/sonar/batch/CheckProfileProvider.java new file mode 100644 index 00000000000..3ec7d8b522b --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/CheckProfileProvider.java @@ -0,0 +1,64 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.picocontainer.injectors.ProviderAdapter; +import org.sonar.api.checks.profiles.Check; +import org.sonar.api.checks.profiles.CheckProfile; +import org.sonar.api.profiles.RulesProfile; +import org.sonar.api.rules.ActiveRule; +import org.sonar.api.rules.ActiveRuleParam; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class CheckProfileProvider extends ProviderAdapter { + + private CheckProfile profile = null; + + public CheckProfile provide(RulesProfile ruleProfile) { + if (profile == null) { + profile = new CheckProfile(ruleProfile.getName(), ruleProfile.getLanguage()); + for (ActiveRule activeRule : ruleProfile.getActiveRules()) { + Check check = toCheck(activeRule); + profile.addCheck(check); + } + } + return profile; + } + + private Check toCheck(ActiveRule activeRule) { + Check check = new Check(activeRule.getPluginName(), activeRule.getRuleKey()); + check.setPriority(activeRule.getPriority().toCheckPriority()); + check.setProperties(toParameters(activeRule.getActiveRuleParams())); + return check; + } + + private Map<String, String> toParameters(List<ActiveRuleParam> params) { + Map<String, String> map = new HashMap<String, String>(); + if (params != null) { + for (ActiveRuleParam param : params) { + map.put(param.getRuleParam().getKey(), param.getValue()); + } + } + return map; + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/CoreJob.java b/sonar-batch/src/main/java/org/sonar/batch/CoreJob.java new file mode 100644 index 00000000000..f7231d63e79 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/CoreJob.java @@ -0,0 +1,29 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.sonar.api.batch.SensorContext; +import org.sonar.api.resources.Project; + +public interface CoreJob { + + void execute(Project project, SensorContext context); + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/CoreJobs.java b/sonar-batch/src/main/java/org/sonar/batch/CoreJobs.java new file mode 100644 index 00000000000..e3beb96ce2a --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/CoreJobs.java @@ -0,0 +1,43 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import java.util.ArrayList; +import java.util.List; + +/** + * Core batch extensions, instanciated by picocontainer. + */ +public final class CoreJobs { + + private CoreJobs() { + } + + public static List<Class<? extends CoreJob>> allJobs() { + List<Class<? extends CoreJob>> classes = new ArrayList<Class<? extends CoreJob>>(); + classes.add(MavenPluginsConfigurator.class); + classes.add(MavenPhaseExecutor.class); + classes.add(SensorsExecutor.class); + classes.add(DecoratorsExecutor.class); + classes.add(FinalizeSnapshotsJob.class); + classes.add(PostJobsExecutor.class); + return classes; + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/DecoratorsExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/DecoratorsExecutor.java new file mode 100644 index 00000000000..f6f5233ae18 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/DecoratorsExecutor.java @@ -0,0 +1,81 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.batch.BatchExtensionDictionnary; +import org.sonar.api.batch.Decorator; +import org.sonar.api.batch.DecoratorContext; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.Resource; +import org.sonar.batch.indexer.DefaultSonarIndex; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class DecoratorsExecutor implements CoreJob { + + private DecoratorsSelector decoratorsSelector; + private DatabaseSession session; + private ViolationsDao violationsDao; + private static final Logger LOG = LoggerFactory.getLogger(DecoratorsExecutor.class); + private DefaultSonarIndex index; + + public DecoratorsExecutor(BatchExtensionDictionnary extensionDictionnary, DefaultSonarIndex index, DatabaseSession session, ViolationsDao violationsDao) { + this.decoratorsSelector = new DecoratorsSelector(extensionDictionnary); + this.session = session; + this.violationsDao = violationsDao; + this.index = index; + } + + + public void execute(Project project, SensorContext sensorContext) { + LoggerFactory.getLogger(DecoratorsExecutor.class).info("Execute decorators..."); + Collection<Decorator> decorators = decoratorsSelector.select(project); + + if (LOG.isDebugEnabled()) { + LOG.debug("Decorators: {}", StringUtils.join(decorators, " -> ")); + } + + decorateResource(project, decorators, true); + } + + private DecoratorContext decorateResource(Resource resource, Collection<Decorator> decorators, boolean executeDecorators) { + List<DecoratorContext> childrenContexts = new ArrayList<DecoratorContext>(); + for (Resource child : index.getChildren(resource)) { + boolean isModule = (child instanceof Project); + DefaultDecoratorContext childContext = (DefaultDecoratorContext) decorateResource(child, decorators, !isModule); + childrenContexts.add(childContext.setReadOnly(true)); + } + + DefaultDecoratorContext context = new DefaultDecoratorContext(resource, index, childrenContexts, session, violationsDao); + if (executeDecorators) { + for (Decorator decorator : decorators) { + decorator.decorate(resource, context); + } + } + return context; + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/DecoratorsSelector.java b/sonar-batch/src/main/java/org/sonar/batch/DecoratorsSelector.java new file mode 100644 index 00000000000..8f8c000099e --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/DecoratorsSelector.java @@ -0,0 +1,62 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.sonar.api.batch.BatchExtensionDictionnary; +import org.sonar.api.batch.Decorator; +import org.sonar.api.batch.FormulaDecorator; +import org.sonar.api.measures.Metric; +import org.sonar.api.resources.Project; + +import java.util.*; + +public class DecoratorsSelector { + + private BatchExtensionDictionnary dictionnary; + + public DecoratorsSelector(BatchExtensionDictionnary dictionnary) { + this.dictionnary = dictionnary; + } + + public Collection<Decorator> select(Project project) { + List<Decorator> decorators = new ArrayList<Decorator>(dictionnary.select(Decorator.class, project, false)); + Set<Metric> coveredMetrics = getMetricsCoveredByPlugins(decorators); + for (Metric metric : dictionnary.select(Metric.class)) { + if (metric.getFormula() != null && !coveredMetrics.contains(metric)) { + decorators.add(new FormulaDecorator(metric)); + } + } + + return dictionnary.sort(decorators); + } + + private Set<Metric> getMetricsCoveredByPlugins(Collection<Decorator> pluginDecorators) { + Set<Metric> coveredMetrics = new HashSet<Metric>(); + for (Decorator pluginDecorator : pluginDecorators) { + List dependents = dictionnary.getDependents(pluginDecorator); + for (Object dependent : dependents) { + if (dependent instanceof Metric) { + coveredMetrics.add((Metric) dependent); + } + } + } + return coveredMetrics; + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/DefaultDecoratorContext.java b/sonar-batch/src/main/java/org/sonar/batch/DefaultDecoratorContext.java new file mode 100644 index 00000000000..05314d3040e --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/DefaultDecoratorContext.java @@ -0,0 +1,177 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.sonar.api.batch.DecoratorContext; +import org.sonar.api.batch.Event; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.design.Dependency; +import org.sonar.api.measures.Measure; +import org.sonar.api.measures.MeasuresFilter; +import org.sonar.api.measures.MeasuresFilters; +import org.sonar.api.measures.Metric; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.Resource; +import org.sonar.api.rules.Violation; +import org.sonar.batch.indexer.Bucket; +import org.sonar.batch.indexer.DefaultSonarIndex; + +import java.util.*; + +public class DefaultDecoratorContext implements DecoratorContext { + + private DatabaseSession session; + private DefaultSonarIndex index; + private Resource resource; + private boolean readOnly = false; + + private List<DecoratorContext> childrenContexts; + private List<Violation> violations; + private ViolationsDao violationsDao; + + public DefaultDecoratorContext(Resource resource, + DefaultSonarIndex index, + List<DecoratorContext> childrenContexts, + DatabaseSession session, + ViolationsDao violationsDao) { + this.index = index; + this.session = session; + this.resource = resource; + this.childrenContexts = childrenContexts; + this.violationsDao = violationsDao; + } + + public DefaultDecoratorContext setReadOnly(boolean b) { + readOnly = b; + violations = null; + childrenContexts = null; + return this; + } + + public Project getProject() { + return index.getProject(); + } + + public List<DecoratorContext> getChildren() { + checkReadOnly("getModules"); + return childrenContexts; + } + + private void checkReadOnly(String methodName) { + if (readOnly) { + throw new IllegalStateException("Method DecoratorContext." + methodName + "() can not be executed on children."); + } + } + + public <M> M getMeasures(MeasuresFilter<M> filter) { + return index.getMeasures(resource, filter); + } + + public Measure getMeasure(Metric metric) { + return index.getMeasures(resource, MeasuresFilters.metric(metric)); + } + + public Collection<Measure> getChildrenMeasures(MeasuresFilter filter) { + List<Measure> result = new ArrayList<Measure>(); + for (DecoratorContext childContext : childrenContexts) { + Object childResult = childContext.getMeasures(filter); + if (childResult != null) { + if (childResult instanceof Collection) { + result.addAll((Collection) childResult); + } else { + result.add((Measure) childResult); + } + } + } + return result; + } + + public Collection<Measure> getChildrenMeasures(Metric metric) { + return getChildrenMeasures(MeasuresFilters.metric(metric)); + } + + public Resource getResource() { + return resource; + } + + public DecoratorContext saveMeasure(Measure measure) { + checkReadOnly("saveMeasure"); + index.saveMeasure(resource, measure); + return this; + } + + public DecoratorContext saveMeasure(Metric metric, Double value) { + checkReadOnly("saveMeasure"); + index.saveMeasure(resource, new Measure(metric, value)); + return this; + } + + + public List<Violation> getViolations() { + if (violations == null) { + Bucket bucket = index.getBucket(resource); + if (bucket != null && bucket.getSnapshotId() != null) { + violations = violationsDao.getViolations(resource, bucket.getSnapshotId()); + } + } + return violations; + } + + public Dependency saveDependency(Dependency dependency) { + checkReadOnly("saveDependency"); + return index.saveDependency(dependency); + } + + public Set<Dependency> getDependencies() { + return index.getDependencies(); + } + + public Collection<Dependency> getIncomingDependencies() { + return index.getIncomingEdges(resource); + } + + public Collection<Dependency> getOutgoingDependencies() { + return index.getOutgoingEdges(resource); + } + + protected DatabaseSession getSession() { + return session; + } + + public List<Event> getEvents() { + return index.getEvents(resource); + } + + public Event createEvent(String name, String description, String category, Date date) { + return index.createEvent(resource, name, description, category, date); + } + + public void deleteEvent(Event event) { + index.deleteEvent(event); + } + + public DefaultDecoratorContext saveViolation(Violation violation) { + if (violation.getResource() == null) { + violation.setResource(resource); + } + index.addViolation(violation); + return this; + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/DefaultSensorContext.java b/sonar-batch/src/main/java/org/sonar/batch/DefaultSensorContext.java new file mode 100644 index 00000000000..de2629ed336 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/DefaultSensorContext.java @@ -0,0 +1,155 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.sonar.api.batch.Event; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.design.Dependency; +import org.sonar.api.measures.Measure; +import org.sonar.api.measures.MeasuresFilter; +import org.sonar.api.measures.Metric; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.ProjectLink; +import org.sonar.api.resources.Resource; +import org.sonar.api.rules.Violation; +import org.sonar.batch.indexer.DefaultSonarIndex; + +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Set; + +public class DefaultSensorContext implements SensorContext { + + private DefaultSonarIndex index; + private Project project; + + public DefaultSensorContext(DefaultSonarIndex index, Project project) { + this.index = index; + this.project = project; + } + + public Project getProject() { + return project; + } + + public Measure getMeasure(Metric metric) { + return index.getMeasure(project, metric); + } + + public <M> M getMeasures(MeasuresFilter<M> filter) { + return index.getMeasures(project, filter); + } + + public Measure saveMeasure(Measure measure) { + return index.saveMeasure(project, measure); + } + + public Measure saveMeasure(Metric metric, Double value) { + return index.saveMeasure(project, new Measure(metric, value)); + } + + public Measure getMeasure(Resource resource, Metric metric) { + return index.getMeasure(resource, metric); + } + + public String saveResource(Resource resource) { + Resource persistedResource = index.addResource(resource); + if (persistedResource!=null) { + return persistedResource.getEffectiveKey(); + } + return null; + } + + public Resource getResource(Resource resource) { + return index.getResource(resource); + } + + public <M> M getMeasures(Resource resource, MeasuresFilter<M> filter) { + return index.getMeasures(resource, filter); + } + + public Measure saveMeasure(Resource resource, Metric metric, Double value) { + return index.saveMeasure(resourceOrProject(resource), new Measure(metric, value)); + } + + public Measure saveMeasure(Resource resource, Measure measure) { + return index.saveMeasure(resourceOrProject(resource), measure); + } + + public void saveViolation(Violation violation) { + if (violation.getResource()==null) { + violation.setResource(resourceOrProject(violation.getResource())); + } + index.addViolation(violation); + } + + public void saveViolations(Collection<Violation> violations) { + if (violations!=null) { + for (Violation violation : violations) { + saveViolation(violation); + } + } + } + + public Dependency saveDependency(Dependency dependency) { + return index.saveDependency(dependency); + } + + public Set<Dependency> getDependencies() { + return index.getDependencies(); + } + + public Collection<Dependency> getIncomingDependencies(Resource to) { + return index.getIncomingEdges(resourceOrProject(to)); + } + + public Collection<Dependency> getOutgoingDependencies(Resource from) { + return index.getOutgoingEdges(resourceOrProject(from)); + } + + public void saveSource(Resource resource, String source) { + index.setSource(resource, source); + } + + public void saveLink(ProjectLink link) { + index.saveLink(link); + } + + public void deleteLink(String key) { + index.deleteLink(key); + } + + public List<Event> getEvents(Resource resource) { + return index.getEvents(resource); + } + + public Event createEvent(Resource resource, String name, String description, String category, Date date) { + return index.createEvent(resource, name, description, category, date); + } + + public void deleteEvent(Event event) { + index.deleteEvent(event); + } + + private Resource resourceOrProject(Resource resource) { + return (resource!=null ? resource : project); + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/DefaultTimeMachine.java b/sonar-batch/src/main/java/org/sonar/batch/DefaultTimeMachine.java new file mode 100644 index 00000000000..092b389f1f3 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/DefaultTimeMachine.java @@ -0,0 +1,116 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.sonar.api.batch.TimeMachine; +import org.sonar.api.batch.TimeMachineQuery; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.model.MeasureModel; +import org.sonar.api.database.model.Snapshot; +import org.sonar.api.measures.Measure; +import org.sonar.api.resources.Resource; +import org.sonar.batch.indexer.DefaultSonarIndex; +import org.sonar.jpa.dao.MeasuresDao; + +import java.util.*; +import javax.persistence.Query; + +public class DefaultTimeMachine implements TimeMachine { + + private DatabaseSession session; + private DefaultSonarIndex index; + private MeasuresDao measuresDao; + + public DefaultTimeMachine(DatabaseSession session, DefaultSonarIndex index, MeasuresDao measuresDao) { + this.session = session; + this.index = index; + this.measuresDao = measuresDao; + } + + public List<Measure> getMeasures(TimeMachineQuery query) { + List<Object[]> objects = execute(query, true); + List<Measure> result = new ArrayList<Measure>(); + + for (Object[] object : objects) { + MeasureModel model = (MeasureModel) object[0]; + Measure measure = model.toMeasure(); + measure.setDate((Date) object[1]); + result.add(measure); + } + return result; + } + + public List<Object[]> getMeasuresFields(TimeMachineQuery query) { + return execute(query, false); + } + + protected List execute(TimeMachineQuery query, boolean selectAllFields) { + Resource resource = index.getResource(query.getResource()); + if (resource == null) { + return Collections.emptyList(); + } + + StringBuilder sb = new StringBuilder(); + Map<String, Object> params = new HashMap<String, Object>(); + + if (selectAllFields) { + sb.append("SELECT m, s.createdAt "); + } else { + sb.append("SELECT s.createdAt, m.metric, m.value "); + } + sb.append(" FROM " + MeasureModel.class.getSimpleName() + " m, " + Snapshot.class.getSimpleName() + " s WHERE m.snapshotId=s.id AND s.resourceId=:resourceId AND s.status=:status AND m.characteristic IS NULL "); + params.put("resourceId", resource.getId()); + params.put("status", Snapshot.STATUS_PROCESSED); + + sb.append(" AND m.rule IS NULL AND m.rulePriority IS NULL AND m.rulesCategoryId IS NULL "); + if (query.getMetrics() != null) { + sb.append(" AND m.metric IN (:metrics) "); + params.put("metrics", measuresDao.getMetrics(query.getMetrics())); + } + if (query.isFromCurrentAnalysis()) { + sb.append(" AND s.createdAt>=:from "); + params.put("from", index.getProject().getAnalysisDate()); + + } else if (query.getFrom() != null) { + sb.append(" AND s.createdAt>=:from "); + params.put("from", query.getFrom()); + } + if (query.isToCurrentAnalysis()) { + sb.append(" AND s.createdAt<=:to "); + params.put("to", index.getProject().getAnalysisDate()); + + } else if (query.getTo() != null) { + sb.append(" AND s.createdAt<=:to "); + params.put("to", query.getTo()); + } + if (query.isOnlyLastAnalysis()) { + sb.append(" AND s.last=:last "); + params.put("last", Boolean.TRUE); + } + sb.append(" ORDER BY s.createdAt "); + + Query jpaQuery = session.createQuery(sb.toString()); + + for (Map.Entry<String, Object> entry : params.entrySet()) { + jpaQuery.setParameter(entry.getKey(), entry.getValue()); + } + return jpaQuery.getResultList(); + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/FinalizeSnapshotsJob.java b/sonar-batch/src/main/java/org/sonar/batch/FinalizeSnapshotsJob.java new file mode 100644 index 00000000000..e1763c5f403 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/FinalizeSnapshotsJob.java @@ -0,0 +1,122 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.batch.Purge; +import org.sonar.api.batch.PurgeContext; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.model.Snapshot; +import org.sonar.api.resources.Project; +import org.sonar.api.utils.TimeProfiler; +import org.sonar.core.purge.DefaultPurgeContext; + +import javax.persistence.Query; + +public class FinalizeSnapshotsJob implements CoreJob { + + private DatabaseSession session; + private Purge[] purges; + private ServerMetadata server; + private Snapshot snapshot; + + public FinalizeSnapshotsJob(ServerMetadata server, DatabaseSession session, Purge[] purges, Snapshot snapshot) { + this.session = session; + this.purges = purges; + this.server = server; + this.snapshot = snapshot; + } + + public void execute(Project project, SensorContext context) { + if (shouldExecuteOn(project)) { + Snapshot previousLastSnapshot = getPreviousLastSnapshot(snapshot); + updateFlags(snapshot, previousLastSnapshot); + purge(snapshot, previousLastSnapshot); + } + } + + private boolean shouldExecuteOn(Project project) { + return project.isRoot(); + } + + private Snapshot getPreviousLastSnapshot(Snapshot snapshot) { + Query query = session.createQuery( + "SELECT s FROM " + Snapshot.class.getSimpleName() + " s " + + "WHERE s.last=true AND s.resourceId=:resourceId"); + query.setParameter("resourceId", snapshot.getResourceId()); + return session.getSingleResult(query, null); + } + + + private void updateFlags(Snapshot rootSnapshot, Snapshot previousLastSnapshot) { + if (previousLastSnapshot != null && previousLastSnapshot.getCreatedAt().before(rootSnapshot.getCreatedAt())) { + setFlags(previousLastSnapshot, false, null); + } + + boolean isLast = (previousLastSnapshot == null || previousLastSnapshot.getCreatedAt().before(rootSnapshot.getCreatedAt())); + setFlags(rootSnapshot, isLast, Snapshot.STATUS_PROCESSED); + LoggerFactory.getLogger(getClass()).info("ANALYSIS SUCCESSFUL, you can browse {}", server.getUrl()); + } + + private void setFlags(Snapshot snapshot, boolean last, String status) { + String hql = "UPDATE " + Snapshot.class.getSimpleName() + " SET last=:last"; + if (status != null) { + hql += ", status=:status "; + } + hql += " WHERE root_snapshot_id=:rootId OR id=:rootId OR (path LIKE :path AND root_snapshot_id=:pathRootId)"; + + Query query = session.createQuery(hql); + if (status != null) { + query.setParameter("status", status); + snapshot.setStatus(status); + } + query.setParameter("last", last); + query.setParameter("rootId", snapshot.getId()); + query.setParameter("path", snapshot.getPath() + snapshot.getId() + ".%"); + query.setParameter("pathRootId", (snapshot.getRootId() == null ? snapshot.getId() : snapshot.getRootId())); + query.executeUpdate(); + session.commit(); + + snapshot.setLast(last); + } + + private void purge(Snapshot currentSnapshot, Snapshot previousLastSnapshot) { + final Logger logger = LoggerFactory.getLogger(FinalizeSnapshotsJob.class); + TimeProfiler profiler = new TimeProfiler(logger).start("Database optimization"); + PurgeContext context = createPurgeContext(currentSnapshot, previousLastSnapshot); + logger.debug("Snapshots to purge: " + context); + for (Purge purge : purges) { + logger.debug("Executing {}...", purge.getClass().getName()); + purge.purge(context); + } + profiler.stop(); + } + + private PurgeContext createPurgeContext(Snapshot currentSnapshot, Snapshot previousLastSnapshot) { + DefaultPurgeContext context = new DefaultPurgeContext(currentSnapshot); + if (previousLastSnapshot != null && previousLastSnapshot.getCreatedAt().before(currentSnapshot.getCreatedAt())) { + context.setLastSnapshotId(previousLastSnapshot.getId()); + } + return context; + } + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/MavenPhaseExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/MavenPhaseExecutor.java new file mode 100644 index 00000000000..78b490b5428 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/MavenPhaseExecutor.java @@ -0,0 +1,42 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.apache.commons.lang.StringUtils; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.resources.Project; + +public class MavenPhaseExecutor implements CoreJob { + + public static final String PROP_PHASE = "sonar.phase"; + + private MavenPluginExecutor executor; + + public MavenPhaseExecutor(MavenPluginExecutor executor) { + this.executor = executor; + } + + public void execute(Project project, SensorContext context) { + String mavenPhase = (String) project.getProperty(PROP_PHASE); + if (!StringUtils.isBlank(mavenPhase)) { + executor.execute(project, mavenPhase); + } + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/MavenPluginExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/MavenPluginExecutor.java new file mode 100644 index 00000000000..12404e58534 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/MavenPluginExecutor.java @@ -0,0 +1,32 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.sonar.api.BatchComponent; +import org.sonar.api.batch.maven.MavenPluginHandler; +import org.sonar.api.resources.Project; + +public interface MavenPluginExecutor extends BatchComponent { + + void execute(Project project, String goal); + + MavenPluginHandler execute(Project project, MavenPluginHandler handler); + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/MavenPluginsConfigurator.java b/sonar-batch/src/main/java/org/sonar/batch/MavenPluginsConfigurator.java new file mode 100644 index 00000000000..ea263a21325 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/MavenPluginsConfigurator.java @@ -0,0 +1,75 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.apache.commons.io.IOUtils; +import org.apache.maven.project.MavenProject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.batch.BatchExtensionDictionnary; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.batch.maven.MavenPlugin; +import org.sonar.api.batch.maven.MavenPluginHandler; +import org.sonar.api.resources.Project; +import org.sonar.api.utils.SonarException; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; + +public class MavenPluginsConfigurator implements CoreJob { + + private BatchExtensionDictionnary dictionnary = null; + + public MavenPluginsConfigurator(BatchExtensionDictionnary dictionnary) { + this.dictionnary = dictionnary; + } + + public void execute(Project project, SensorContext context) { + Logger logger = LoggerFactory.getLogger(getClass()); + logger.info("Configure maven plugins..."); + + for (MavenPluginHandler handler : dictionnary.selectMavenPluginHandlers(project)) { + logger.debug("Configure {}...", handler); + configureHandler(project, handler); + } + savePom(project); + } + + protected void configureHandler(Project project, MavenPluginHandler handler) { + MavenPlugin plugin = MavenPlugin.registerPlugin(project.getPom(), handler.getGroupId(), handler.getArtifactId(), handler.getVersion(), handler.isFixedVersion()); + handler.configure(project, plugin); + } + + protected void savePom(Project project) { + MavenProject pom = project.getPom(); + File targetPom = new File(project.getFileSystem().getSonarWorkingDirectory(), "sonar-pom.xml"); + FileWriter fileWriter = null; + try { + fileWriter = new FileWriter(targetPom, false); + pom.writeModel(fileWriter); + + } catch (IOException e) { + throw new SonarException("Can not save pom to " + targetPom, e); + } finally { + IOUtils.closeQuietly(fileWriter); + } + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/PostJobsExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/PostJobsExecutor.java new file mode 100644 index 00000000000..1df8d3fd773 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/PostJobsExecutor.java @@ -0,0 +1,81 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.batch.BatchExtensionDictionnary; +import org.sonar.api.batch.PostJob; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.batch.maven.DependsUponMavenPlugin; +import org.sonar.api.batch.maven.MavenPluginHandler; +import org.sonar.api.resources.Project; + +import java.util.Collection; + +public class PostJobsExecutor implements CoreJob { + private static final Logger LOG = LoggerFactory.getLogger(PostJobsExecutor.class); + + private Collection<PostJob> postJobs; + private MavenPluginExecutor mavenExecutor; + + public PostJobsExecutor(Project project, BatchExtensionDictionnary selector, MavenPluginExecutor mavenExecutor) { + postJobs = selector.select(PostJob.class, project, true); + this.mavenExecutor = mavenExecutor; + } + + protected PostJobsExecutor(Collection<PostJob> postJobs, MavenPluginExecutor mavenExecutor) { + this.postJobs = postJobs; + this.mavenExecutor = mavenExecutor; + } + + public void execute(Project project, SensorContext context) { + if (shouldExecuteOn(project)) { + logPostJobs(); + + for (PostJob postJob : postJobs) { + LOG.info("Executing post-job {}", postJob.getClass()); + executeMavenPlugin(project, postJob); + postJob.executeOn(project, context); + } + } + } + + private void logPostJobs() { + if (LOG.isDebugEnabled()) { + LOG.debug("Post-jobs : {}", StringUtils.join(postJobs, " -> ")); + } + } + + private boolean shouldExecuteOn(Project project) { + return postJobs != null && project.isRoot(); + } + + + private void executeMavenPlugin(Project project, PostJob job) { + if (job instanceof DependsUponMavenPlugin) { + MavenPluginHandler handler = ((DependsUponMavenPlugin) job).getMavenPluginHandler(project); + if (handler != null) { + mavenExecutor.execute(project, handler); + } + } + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/ProfileProvider.java b/sonar-batch/src/main/java/org/sonar/batch/ProfileProvider.java new file mode 100644 index 00000000000..2059f562c69 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/ProfileProvider.java @@ -0,0 +1,66 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.picocontainer.injectors.ProviderAdapter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.jpa.dao.ProfilesDao; +import org.sonar.api.profiles.RulesProfile; +import org.sonar.api.resources.Project; +import org.sonar.api.rules.ActiveRule; + +public class ProfileProvider extends ProviderAdapter { + + public static final String PARAM_PROFILE = "sonar.profile"; + + private static final Logger LOG = LoggerFactory.getLogger(ProfileProvider.class); + private RulesProfile profile; + + public RulesProfile provide(Project project, ProfilesDao dao) { + if (profile == null) { + String profileName = (String) project.getProperty(PARAM_PROFILE); + if (profileName == null) { + Project root = project.getRoot(); + profile = dao.getActiveProfile(root.getLanguageKey(), root.getKey()); + if (profile == null) { + throw new RuntimeException("Quality profile not found for " + root.getKey() + ", language " + root.getLanguageKey()); + } + + } else { + profile = dao.getProfile(project.getLanguageKey(), profileName); + if (profile == null) { + throw new RuntimeException("Quality profile not found : " + profileName + ", language " + project.getLanguageKey()); + } + } + + // hack to lazy initialize the profile collections + profile.getActiveRules().size(); + for (ActiveRule activeRule : profile.getActiveRules()) { + activeRule.getActiveRuleParams().size(); + activeRule.getRule().getParams().size(); + } + profile.getAlerts().size(); + + LOG.info("Selected quality profile : {}", profile); + } + return profile; + } +}
\ No newline at end of file diff --git a/sonar-batch/src/main/java/org/sonar/batch/ProjectBatch.java b/sonar-batch/src/main/java/org/sonar/batch/ProjectBatch.java new file mode 100644 index 00000000000..2f0894a2c61 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/ProjectBatch.java @@ -0,0 +1,141 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.picocontainer.Characteristics; +import org.picocontainer.MutablePicoContainer; +import org.sonar.api.batch.BatchExtensionDictionnary; +import org.sonar.api.batch.ProjectClasspath; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Metric; +import org.sonar.api.measures.Metrics; +import org.sonar.api.resources.Languages; +import org.sonar.api.resources.Project; +import org.sonar.api.rules.DefaultRulesManager; +import org.sonar.api.utils.IocContainer; +import org.sonar.batch.indexer.DefaultSonarIndex; +import org.sonar.core.qualitymodel.DefaultModelProvider; +import org.sonar.core.rule.DefaultRuleProvider; +import org.sonar.jpa.dao.*; + +public class ProjectBatch { + + private MutablePicoContainer globalContainer; + private MutablePicoContainer batchContainer; + + public ProjectBatch(MutablePicoContainer container) { + this.globalContainer = container; + } + + public void execute(DefaultSonarIndex index, Project project) { + try { + startChildContainer(index, project); + SensorContext sensorContext = batchContainer.getComponent(SensorContext.class); + for (Class<? extends CoreJob> clazz : CoreJobs.allJobs()) { + CoreJob job = getComponent(clazz); + job.execute(project, sensorContext); + commit(); + } + + } finally { + index.clear(); + stop(); + } + } + + public void startChildContainer(DefaultSonarIndex index, Project project) { + batchContainer = globalContainer.makeChildContainer(); + batchContainer.getComponent(BatchPluginRepository.class).registerPlugins(batchContainer); + + batchContainer.as(Characteristics.CACHE).addComponent(project); + batchContainer.as(Characteristics.CACHE).addComponent(project.getPom()); + batchContainer.as(Characteristics.CACHE).addComponent(ProjectClasspath.class); + batchContainer.as(Characteristics.CACHE).addComponent(index.getBucket(project).getSnapshot()); + batchContainer.as(Characteristics.CACHE).addComponent(project.getConfiguration()); + + batchContainer.as(Characteristics.CACHE).addComponent(DaoFacade.class); + batchContainer.as(Characteristics.CACHE).addComponent(RulesDao.class); + batchContainer.as(Characteristics.CACHE).addComponent(org.sonar.api.database.daos.RulesDao.class); + batchContainer.as(Characteristics.CACHE).addComponent(MeasuresDao.class); + batchContainer.as(Characteristics.CACHE).addComponent(org.sonar.api.database.daos.MeasuresDao.class); + batchContainer.as(Characteristics.CACHE).addComponent(ProfilesDao.class); + batchContainer.as(Characteristics.CACHE).addComponent(AsyncMeasuresDao.class); + batchContainer.as(Characteristics.CACHE).addComponent(AsyncMeasuresService.class); + batchContainer.as(Characteristics.CACHE).addComponent(DefaultRulesManager.class); + batchContainer.as(Characteristics.CACHE).addComponent(DefaultSensorContext.class); + batchContainer.as(Characteristics.CACHE).addComponent(Languages.class); + batchContainer.as(Characteristics.CACHE).addComponent(BatchExtensionDictionnary.class); + batchContainer.as(Characteristics.CACHE).addComponent(DefaultTimeMachine.class); + batchContainer.as(Characteristics.CACHE).addComponent(ViolationsDao.class); + batchContainer.as(Characteristics.CACHE).addComponent(ViolationFilters.class); + batchContainer.as(Characteristics.CACHE).addComponent(ResourceFilters.class); + batchContainer.as(Characteristics.CACHE).addComponent(DefaultModelProvider.class); + batchContainer.as(Characteristics.CACHE).addComponent(DefaultRuleProvider.class); + batchContainer.addAdapter(new ProfileProvider()); + batchContainer.addAdapter(new CheckProfileProvider()); + loadCoreComponents(batchContainer); + batchContainer.as(Characteristics.CACHE).addComponent(new IocContainer(batchContainer)); + batchContainer.start(); + + // post-initializations + project.setLanguage(getComponent(Languages.class).get(project.getLanguageKey())); + index.selectProject(project, getComponent(ResourceFilters.class), getComponent(ViolationFilters.class), getComponent(MeasuresDao.class), getComponent(ViolationsDao.class)); + } + + private void loadCoreComponents(MutablePicoContainer container) { + for (Class<?> clazz : CoreJobs.allJobs()) { + container.as(Characteristics.CACHE).addComponent(clazz); + } + for (Metric metric : CoreMetrics.getMetrics()) { + container.as(Characteristics.CACHE).addComponent(metric.getKey(), metric); + } + for (Metrics metricRepo : container.getComponents(Metrics.class)) { + for (Metric metric : metricRepo.getMetrics()) { + container.as(Characteristics.CACHE).addComponent(metric.getKey(), metric); + } + } + } + + private void stop() { + if (batchContainer != null) { + commit(); + try { + globalContainer.removeChildContainer(batchContainer); + batchContainer.stop(); + batchContainer=null; + } catch (Exception e) { + // do not log + } + } + } + + public void commit() { + getComponent(DatabaseSession.class).commit(); + } + + public <T> T getComponent(Class<T> clazz) { + if (batchContainer != null) { + return batchContainer.getComponent(clazz); + } + return globalContainer.getComponent(clazz); + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/ProjectBuilder.java b/sonar-batch/src/main/java/org/sonar/batch/ProjectBuilder.java new file mode 100644 index 00000000000..3389db5e268 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/ProjectBuilder.java @@ -0,0 +1,150 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.apache.commons.configuration.*; +import org.apache.commons.lang.time.DateUtils; +import org.apache.maven.project.MavenProject; +import org.sonar.api.CoreProperties; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.model.ResourceModel; +import org.sonar.api.database.model.Snapshot; +import org.sonar.api.resources.DefaultProjectFileSystem; +import org.sonar.api.resources.Java; +import org.sonar.api.resources.Project; +import org.sonar.api.utils.SonarException; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class ProjectBuilder { + + private DatabaseSession databaseSession; + + public ProjectBuilder(DatabaseSession databaseSession) { + this.databaseSession = databaseSession; + } + + public Project create(MavenProject pom) { + Configuration configuration = getStartupConfiguration(pom); + return new Project(loadProjectKey(pom), loadProjectBranch(configuration), pom.getName()) + .setPom(pom) + .setDescription(pom.getDescription()) + .setPackaging(pom.getPackaging()); + } + + Configuration getStartupConfiguration(MavenProject pom) { + CompositeConfiguration configuration = new CompositeConfiguration(); + configuration.addConfiguration(new SystemConfiguration()); + configuration.addConfiguration(new EnvironmentConfiguration()); + configuration.addConfiguration(new MapConfiguration(pom.getModel().getProperties())); + return configuration; + } + + String loadProjectKey(MavenProject pom) { + return new StringBuilder().append(pom.getGroupId()).append(":").append(pom.getArtifactId()).toString(); + } + + String loadProjectBranch(Configuration configuration) { + return configuration.getString(CoreProperties.PROJECT_BRANCH_PROPERTY, configuration.getString("branch" /* deprecated property */)); + } + + + public void configure(Project project) { + ProjectConfiguration projectConfiguration = new ProjectConfiguration(databaseSession, project); + configure(project, projectConfiguration); + } + + + void configure(Project project, Configuration projectConfiguration) { + Date analysisDate = loadAnalysisDate(projectConfiguration); + project.setConfiguration(projectConfiguration) + .setExclusionPatterns(loadExclusionPatterns(projectConfiguration)) + .setAnalysisDate(analysisDate) + .setLatestAnalysis(isLatestAnalysis(project.getKey(), analysisDate)) + .setAnalysisVersion(loadAnalysisVersion(projectConfiguration, project.getPom())) + .setAnalysisType(loadAnalysisType(projectConfiguration)) + .setLanguageKey(loadLanguageKey(projectConfiguration)) + .setFileSystem(new DefaultProjectFileSystem(project)); + } + + static String[] loadExclusionPatterns(Configuration configuration) { + String[] exclusionPatterns = configuration.getStringArray(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY); + if (exclusionPatterns == null) { + exclusionPatterns = new String[0]; + } + return exclusionPatterns; + } + + boolean isLatestAnalysis(String projectKey, Date analysisDate) { + ResourceModel persistedProject = databaseSession.getSingleResult(ResourceModel.class, "key", projectKey, "enabled", true); + if (persistedProject != null) { + Snapshot lastSnapshot = databaseSession.getSingleResult(Snapshot.class, "resourceId", persistedProject.getId(), "last", true); + return lastSnapshot == null || lastSnapshot.getCreatedAt().before(analysisDate); + } + return true; + } + + + Date loadAnalysisDate(Configuration configuration) { + String formattedDate = configuration.getString(CoreProperties.PROJECT_DATE_PROPERTY); + if (formattedDate == null) { + return new Date(); + } + + DateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + try { + // see SONAR-908 make sure that a time is defined for the date. + Date date = DateUtils.setHours(format.parse(formattedDate), 0); + return DateUtils.setMinutes(date, 1); + + } catch (ParseException e) { + throw new SonarException("The property " + CoreProperties.PROJECT_DATE_PROPERTY + " does not respect the format yyyy-MM-dd (for example 2008-05-23) : " + formattedDate, e); + } + } + + Project.AnalysisType loadAnalysisType(Configuration configuration) { + String value = configuration.getString(CoreProperties.DYNAMIC_ANALYSIS_PROPERTY); + if (value == null) { + return (configuration.getBoolean("sonar.light", false) ? Project.AnalysisType.STATIC : Project.AnalysisType.DYNAMIC); + } + if ("true".equals(value)) { + return Project.AnalysisType.DYNAMIC; + } + if ("reuseReports".equals(value)) { + return Project.AnalysisType.REUSE_REPORTS; + } + return Project.AnalysisType.STATIC; + } + + String loadAnalysisVersion(Configuration configuration, MavenProject pom) { + String version = configuration.getString(CoreProperties.PROJECT_VERSION_PROPERTY); + if (version == null && pom != null) { + version = pom.getVersion(); + } + return version; + } + + String loadLanguageKey(Configuration configuration) { + return configuration.getString(CoreProperties.PROJECT_LANGUAGE_PROPERTY, Java.KEY); + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/ProjectConfiguration.java b/sonar-batch/src/main/java/org/sonar/batch/ProjectConfiguration.java new file mode 100644 index 00000000000..4226a14fe7c --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/ProjectConfiguration.java @@ -0,0 +1,68 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.apache.commons.configuration.*; +import org.apache.maven.project.MavenProject; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.resources.Project; + +public class ProjectConfiguration extends CompositeConfiguration { + private PropertiesConfiguration runtimeConfiguration; + + public ProjectConfiguration(DatabaseSession session, Project project) { + runtimeConfiguration = new PropertiesConfiguration(); + addConfiguration(runtimeConfiguration); + + loadSystemSettings(); + loadProjectDatabaseSettings(session, project); + loadMavenSettings(project.getPom()); + loadGlobalDatabaseSettings(session); + } + + private void loadProjectDatabaseSettings(DatabaseSession session, Project project) { + addConfiguration(new ResourceDatabaseConfiguration(session, project.getKey())); + + Project parent = project.getParent(); + while (parent != null && parent.getKey() != null) { + addConfiguration(new ResourceDatabaseConfiguration(session, parent.getKey())); + parent = parent.getParent(); + } + } + + private void loadGlobalDatabaseSettings(DatabaseSession session) { + addConfiguration(new org.sonar.api.database.configuration.DatabaseConfiguration(session)); + } + + private void loadSystemSettings() { + addConfiguration(new SystemConfiguration()); + addConfiguration(new EnvironmentConfiguration()); + } + + private void loadMavenSettings(MavenProject pom) { + addConfiguration(new MapConfiguration(pom.getModel().getProperties())); + } + + @Override + public void setProperty(String s, Object o) { + runtimeConfiguration.setProperty(s, o); + } +} + diff --git a/sonar-batch/src/main/java/org/sonar/batch/ProjectTree.java b/sonar-batch/src/main/java/org/sonar/batch/ProjectTree.java new file mode 100644 index 00000000000..497c4656f58 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/ProjectTree.java @@ -0,0 +1,163 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.project.MavenProject; +import org.slf4j.LoggerFactory; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.resources.Project; + +import java.io.File; +import java.io.IOException; +import java.util.*; + +public class ProjectTree { + + private List<Project> projects; + private List<MavenProject> poms; + private ProjectBuilder projectBuilder; + + public ProjectTree(MavenSession mavenSession, DatabaseSession databaseSession) { + this.poms = mavenSession.getSortedProjects(); + this.projectBuilder = new ProjectBuilder(databaseSession); + } + + /** + * for unit tests + */ + protected ProjectTree(ProjectBuilder projectBuilder, List<MavenProject> poms) { + this.projectBuilder = projectBuilder; + this.poms = poms; + } + + /** + * for unit tests + */ + protected ProjectTree(List<Project> projects) { + this.projects = new ArrayList<Project>(projects); + } + + public void start() throws IOException { + projects = Lists.newArrayList(); + Map<String, Project> paths = Maps.newHashMap(); // projects by canonical path + + for (MavenProject pom : poms) { + Project project = projectBuilder.create(pom); + projects.add(project); + paths.put(pom.getBasedir().getCanonicalPath(), project); + } + + for (Map.Entry<String, Project> entry : paths.entrySet()) { + Project project = entry.getValue(); + MavenProject pom = project.getPom(); + for (Object moduleId : pom.getModules()) { + File modulePath = new File(pom.getBasedir(), (String) moduleId); + Project module = paths.get(modulePath.getCanonicalPath()); + if (module != null) { + module.setParent(project); + } + } + } + + configureProjects(); + applyModuleExclusions(); + } + + private void configureProjects() { + for (Project project : projects) { + projectBuilder.configure(project); + } + } + + void applyModuleExclusions() { + for (Project project : projects) { + String[] excludedArtifactIds = project.getConfiguration().getStringArray("sonar.skippedModules"); + String[] includedArtifactIds = project.getConfiguration().getStringArray("sonar.includedModules"); + + Set<String> includedModulesIdSet = new HashSet<String>(); + Set<String> excludedModulesIdSet = new HashSet<String>(); + + if (includedArtifactIds != null) { + includedModulesIdSet.addAll(Arrays.asList(includedArtifactIds)); + } + + if (excludedArtifactIds != null) { + excludedModulesIdSet.addAll(Arrays.asList(excludedArtifactIds)); + includedModulesIdSet.removeAll(excludedModulesIdSet); + } + + if (!includedModulesIdSet.isEmpty()) { + for (Project currentProject : projects) { + if (!includedModulesIdSet.contains(currentProject.getPom().getArtifactId())) { + exclude(currentProject); + } + } + } else { + for (String excludedArtifactId : excludedModulesIdSet) { + Project excludedProject = getProjectByArtifactId(excludedArtifactId); + exclude(excludedProject); + } + } + } + + for (Iterator<Project> it = projects.iterator(); it.hasNext();) { + Project project = it.next(); + if (project.isExcluded()) { + LoggerFactory.getLogger(getClass()).info("Module {} is excluded from analysis", project.getName()); + project.removeFromParent(); + it.remove(); + } + } + } + + private void exclude(Project project) { + if (project != null) { + project.setExcluded(true); + for (Project module : project.getModules()) { + exclude(module); + } + } + } + + public List<Project> getProjects() { + return projects; + } + + public Project getProjectByArtifactId(String artifactId) { + for (Project project : projects) { + if (project.getPom().getArtifactId().equals(artifactId)) { + return project; + } + } + return null; + } + + public Project getRootProject() { + for (Project project : projects) { + if (project.getParent() == null) { + return project; + } + } + throw new IllegalStateException("Can not find the root project from the list of Maven modules"); + } +}
\ No newline at end of file diff --git a/sonar-batch/src/main/java/org/sonar/batch/RemoteClassLoader.java b/sonar-batch/src/main/java/org/sonar/batch/RemoteClassLoader.java new file mode 100644 index 00000000000..09987c09ecb --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/RemoteClassLoader.java @@ -0,0 +1,69 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.apache.commons.configuration.Configuration; + +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Collection; + +/** + * Create classloader from remote URLs. + * + * IMPORTANT : it generates URLClassLoaders, which use the parent first delegation mode. It finds classes in the parent classloader THEN + * in the plugin classloader. + * Using a child-first delegation mode can avoid some conflicts with API dependencies (xml-api, antlr). It's + * not possible for now, but it would be simple to implement by replacing the URLClassLoader by + * the class ChildFirstClassLoader (see http://articles.qos.ch/classloader.html) + */ +public class RemoteClassLoader { + + private URLClassLoader classLoader; + + public RemoteClassLoader(URL[] urls, ClassLoader parent) { + ClassLoader parentClassLoader = (parent==null ? RemoteClassLoader.class.getClassLoader() : parent); + classLoader = URLClassLoader.newInstance(urls, parentClassLoader); + } + + public RemoteClassLoader(URL[] urls) { + this(urls, null); + } + + public RemoteClassLoader(Collection<URL> urls, ClassLoader parent) { + this(urls.toArray(new URL[urls.size()]), parent); + } + + public URLClassLoader getClassLoader() { + return classLoader; + } + + public static RemoteClassLoader createForJdbcDriver(Configuration conf) { + String baseUrl = ServerMetadata.getUrl(conf); + String url = baseUrl + "/deploy/jdbc-driver.jar"; + try { + return new RemoteClassLoader(new URL[]{new URL(url)}); + + } catch (MalformedURLException e) { + throw new RuntimeException("Fail to download the JDBC driver from server: " + url, e); + } + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/ResourceDatabaseConfiguration.java b/sonar-batch/src/main/java/org/sonar/batch/ResourceDatabaseConfiguration.java new file mode 100644 index 00000000000..77359f427e3 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/ResourceDatabaseConfiguration.java @@ -0,0 +1,83 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.apache.commons.configuration.BaseConfiguration; + +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.configuration.Property; +import org.sonar.api.database.model.ResourceModel; + +import java.util.List; + +public class ResourceDatabaseConfiguration extends BaseConfiguration { + private final DatabaseSession session; + private Integer resourceId = null; + + public ResourceDatabaseConfiguration(DatabaseSession session, ResourceModel resource) { + this.session = session; + if (resource != null) { + this.resourceId = resource.getId(); + } + load(); + } + + public ResourceDatabaseConfiguration(DatabaseSession session, Integer resourceId) { + this.session = session; + this.resourceId = resourceId; + load(); + } + + public ResourceDatabaseConfiguration(DatabaseSession session, String resourceKey) { + this.session = session; + + ResourceModel resource = session.getSingleResult(ResourceModel.class, "key", resourceKey); + if (resource != null) { + this.resourceId = resource.getId(); + } + load(); + } + + public void load() { + clear(); + + loadResourceProperties(); + } + + private void loadResourceProperties() { + if (resourceId != null) { + List<Property> properties = session + .createQuery("from " + Property.class.getSimpleName() + " p where p.resourceId=:resourceId") + .setParameter("resourceId", resourceId) + .getResultList(); + + registerProperties(properties); + } + } + + private void registerProperties(List<Property> properties) { + if (properties != null) { + for (Property property : properties) { + setProperty(property.getKey(), property.getValue()); + } + } + } + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/ResourceFilters.java b/sonar-batch/src/main/java/org/sonar/batch/ResourceFilters.java new file mode 100644 index 00000000000..395ffd2f38b --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/ResourceFilters.java @@ -0,0 +1,65 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.batch.ResourceFilter; +import org.sonar.api.resources.Resource; + +/** + * @since 1.12 + */ +public class ResourceFilters { + + private static final Logger LOG = LoggerFactory.getLogger(ResourceFilters.class); + + private ResourceFilter[] filters; + + public ResourceFilters(ResourceFilter[] filters) { + this.filters = (filters==null ? new ResourceFilter[0] : filters); + } + + public ResourceFilters() { + this(null); + } + + public ResourceFilter[] getFilters() { + return filters; + } + + /** + * Return true if the violation must be saved. If false then it is ignored. + */ + public boolean isExcluded(Resource resource) { + boolean ignored = false; + int index = 0; + while (!ignored && index < filters.length) { + ResourceFilter filter = filters[index]; + ignored = filter.isIgnored(resource); + if (ignored && LOG.isDebugEnabled()) { + LOG.debug("Resource {} is excluded by the filter {}", resource, filter); + } + index++; + } + return ignored; + } + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/SensorsExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/SensorsExecutor.java new file mode 100644 index 00000000000..4bcdc39e9a6 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/SensorsExecutor.java @@ -0,0 +1,74 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.batch.BatchExtensionDictionnary; +import org.sonar.api.batch.Sensor; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.batch.maven.DependsUponMavenPlugin; +import org.sonar.api.batch.maven.MavenPluginHandler; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.resources.Project; +import org.sonar.api.utils.TimeProfiler; + +import java.util.Collection; + +public class SensorsExecutor implements CoreJob { + private static final Logger logger = LoggerFactory.getLogger(SensorsExecutor.class); + + private Collection<Sensor> sensors; + private DatabaseSession session; + private MavenPluginExecutor mavenExecutor; + + public SensorsExecutor(BatchExtensionDictionnary selector, Project project, DatabaseSession session, MavenPluginExecutor mavenExecutor) { + this.sensors = selector.select(Sensor.class, project, true); + this.session = session; + this.mavenExecutor = mavenExecutor; + } + + public void execute(Project project, SensorContext context) { + if (logger.isDebugEnabled()) { + logger.debug("Sensors : {}", StringUtils.join(sensors, " -> ")); + } + + for (Sensor sensor : sensors) { + executeMavenPlugin(project, sensor); + + TimeProfiler profiler = new TimeProfiler(logger).start("Sensor "+ sensor); + sensor.analyse(project, context); + session.commit(); + profiler.stop(); + } + } + + private void executeMavenPlugin(Project project, Sensor sensor) { + if (sensor instanceof DependsUponMavenPlugin) { + MavenPluginHandler handler = ((DependsUponMavenPlugin) sensor).getMavenPluginHandler(project); + if (handler != null) { + TimeProfiler profiler = new TimeProfiler(logger).start("Execute maven plugin " + handler.getArtifactId()); + mavenExecutor.execute(project, handler); + profiler.stop(); + } + } + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/ServerMetadata.java b/sonar-batch/src/main/java/org/sonar/batch/ServerMetadata.java new file mode 100644 index 00000000000..d06e9212e91 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/ServerMetadata.java @@ -0,0 +1,73 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.apache.commons.configuration.Configuration; +import org.apache.commons.lang.StringUtils; +import org.slf4j.LoggerFactory; +import org.sonar.api.CoreProperties; +import org.sonar.api.platform.Server; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class ServerMetadata extends Server { + + private String id; + private String version; + private String url; + private Date startTime; + + public ServerMetadata(Configuration conf) { + id = conf.getString(CoreProperties.SERVER_ID); + version = conf.getString(CoreProperties.SERVER_VERSION); + url = getUrl(conf); + String dateString = conf.getString(CoreProperties.SERVER_STARTTIME); + if (dateString!=null) { + try { + this.startTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").parse(dateString); + + } catch (ParseException e) { + LoggerFactory.getLogger(getClass()).error("The property " + CoreProperties.SERVER_STARTTIME + " is badly formatted.", e); + } + } + } + + public static String getUrl(Configuration conf) { + return StringUtils.removeEnd(conf.getString("sonar.host.url", "http://localhost:9000"), "/"); + } + + public String getId() { + return id; + } + + public String getVersion() { + return version; + } + + public Date getStartedAt() { + return startTime; + } + + public String getUrl() { + return url; + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/ViolationFilters.java b/sonar-batch/src/main/java/org/sonar/batch/ViolationFilters.java new file mode 100644 index 00000000000..784b01ae8b5 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/ViolationFilters.java @@ -0,0 +1,60 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.rules.Violation; +import org.sonar.api.rules.ViolationFilter; + +public class ViolationFilters { + + private static final Logger LOG = LoggerFactory.getLogger(ViolationFilters.class); + + private ViolationFilter[] filters; + + public ViolationFilters(ViolationFilter[] filters) { + this.filters = (filters==null ? new ViolationFilter[0] : filters); + } + + public ViolationFilters() { + this(null); + } + + public ViolationFilter[] getFilters() { + return filters; + } + + /** + * Return true if the violation must be saved. If false then it is ignored. + */ + public boolean isIgnored(Violation violation) { + boolean ignored = false; + int index = 0; + while (!ignored && index < filters.length) { + ignored = filters[index].isIgnored(violation); + if (ignored && LOG.isDebugEnabled()) { + LOG.debug("Violation {} is excluded by the filter {}", violation, filters[index]); + } + index++; + } + return ignored; + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/ViolationsDao.java b/sonar-batch/src/main/java/org/sonar/batch/ViolationsDao.java new file mode 100644 index 00000000000..bdca03188ca --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/ViolationsDao.java @@ -0,0 +1,99 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.slf4j.LoggerFactory; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.model.RuleFailureModel; +import org.sonar.api.database.model.Snapshot; +import org.sonar.api.profiles.RulesProfile; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.Resource; +import org.sonar.api.rules.ActiveRule; +import org.sonar.api.rules.Rule; +import org.sonar.api.rules.Violation; +import org.sonar.jpa.dao.RulesDao; + +import java.util.ArrayList; +import java.util.List; + +public class ViolationsDao { + + private RulesProfile profile; + private DatabaseSession session; + private RulesDao rulesDao; + private boolean reuseExistingRulesConfig; + + public ViolationsDao(RulesProfile profile, DatabaseSession session, RulesDao rulesDao, Project project) { + this.profile = profile; + this.session = session; + this.rulesDao = rulesDao; + this.reuseExistingRulesConfig = project.getReuseExistingRulesConfig(); + } + + public List<Violation> getViolations(Resource resource, Integer snapshotId) { + List<RuleFailureModel> models = session.getResults(RuleFailureModel.class, "snapshotId", snapshotId); + List<Violation> violations = new ArrayList<Violation>(); + for (RuleFailureModel model : models) { + Violation violation = new Violation(model.getRule(), resource); + violation.setLineId(model.getLine()); + violation.setMessage(model.getMessage()); + violation.setPriority(model.getPriority()); + violations.add(violation); + } + return violations; + } + + public void saveViolation(Snapshot snapshot, Violation violation) { + if (profile == null || snapshot == null || violation == null) { + throw new IllegalArgumentException("Missing data to save violation : profile=" + profile + ",snapshot=" + snapshot + ",violation=" + violation); + } + + ActiveRule activeRule = profile.getActiveRule(violation.getRule()); + if (activeRule == null) { + if (reuseExistingRulesConfig) { + activeRule = new ActiveRule(profile, violation.getRule(), violation.getRule().getPriority()); + } else { + LoggerFactory.getLogger(getClass()).debug("Violation is not saved because rule is not activated : violation={}", violation); + } + } + if (activeRule != null) { + RuleFailureModel model = toModel(snapshot, violation, activeRule); + session.save(model); + } + } + + private RuleFailureModel toModel(Snapshot snapshot, Violation violation, ActiveRule activeRule) { + Rule rule = reload(violation.getRule()); + if (rule == null) { + throw new IllegalArgumentException("Rule does not exist : " + violation.getRule()); + } + RuleFailureModel model = new RuleFailureModel(rule, activeRule.getPriority()); + violation.setPriority(activeRule.getPriority()); + model.setLine(violation.getLineId()); + model.setMessage(violation.getMessage()); + model.setSnapshotId(snapshot.getId()); + return model; + } + + private Rule reload(Rule rule) { + return rule.getId() != null ? rule : rulesDao.getRuleByKey(rule.getPluginName(), rule.getKey()); + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/indexer/Bucket.java b/sonar-batch/src/main/java/org/sonar/batch/indexer/Bucket.java new file mode 100644 index 00000000000..98e107a2e4d --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/indexer/Bucket.java @@ -0,0 +1,150 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch.indexer; + +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.ListMultimap; +import com.google.common.collect.Lists; +import org.sonar.api.database.model.Snapshot; +import org.sonar.api.measures.Measure; +import org.sonar.api.measures.MeasuresFilter; +import org.sonar.api.measures.MeasuresFilters; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.Resource; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +public class Bucket<RESOURCE extends Resource> { + + private RESOURCE resource; + private Snapshot snapshot; + private ListMultimap<String, Measure> measuresByMetric = ArrayListMultimap.create(); + private boolean sourceSaved = false; + private Bucket<Project> project; + private Bucket<?> parent; + private List<Bucket<?>> children; + + public Bucket(RESOURCE resource) { + this.resource = resource; + } + + public RESOURCE getResource() { + return resource; + } + + public Bucket<Project> getProject() { + return project; + } + + public Bucket<RESOURCE> setProject(Bucket<Project> project) { + this.project = project; + return this; + } + + public Snapshot getSnapshot() { + return snapshot; + } + + public Integer getSnapshotId() { + if (snapshot != null) { + return snapshot.getId(); + } + return null; + } + + public void setSnapshot(Snapshot snapshot) { + this.snapshot = snapshot; + } + + public void setParent(Bucket parent) { + this.parent = parent; + if (parent != null) { + parent.addChild(this); + } + } + + private void addChild(Bucket bucket) { + if (children == null) { + children = Lists.newArrayList(); + } + children.add(bucket); + } + + private void removeChild(Bucket bucket) { + if (children != null) { + children.remove(bucket); + } + } + + public List<Bucket<?>> getChildren() { + if (children == null) { + return Collections.emptyList(); + } + return children; + } + + public Bucket getParent() { + return parent; + } + + public void addMeasure(Measure measure) { + measuresByMetric.put(measure.getMetric().getKey(), measure); + } + + public boolean isSourceSaved() { + return sourceSaved; + } + + public void setSourceSaved(boolean b) { + this.sourceSaved = b; + } + + public void clear() { + measuresByMetric = null; + children = null; + if (parent != null) { + parent.removeChild(this); + } + } + + public boolean isExcluded() { + return resource.isExcluded(); + } + + public boolean isPersisted() { + return resource.getId() != null; + } + + public Integer getResourceId() { + return resource.getId(); + } + + public <M> M getMeasures(final MeasuresFilter<M> filter) { + Collection<Measure> unfiltered; + if (filter instanceof MeasuresFilters.MetricFilter) { + unfiltered = measuresByMetric.get(((MeasuresFilters.MetricFilter) filter).filterOnMetric().getKey()); + } else { + unfiltered = measuresByMetric.values(); + } + return filter.filter(unfiltered); + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/indexer/DefaultPersister.java b/sonar-batch/src/main/java/org/sonar/batch/indexer/DefaultPersister.java new file mode 100644 index 00000000000..36f8419e083 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/indexer/DefaultPersister.java @@ -0,0 +1,52 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch.indexer; + +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.model.ResourceModel; +import org.sonar.api.database.model.Snapshot; + +public class DefaultPersister extends ResourcePersister { + + public DefaultPersister(DatabaseSession session) { + super(session); + } + + @Override + protected Snapshot createSnapshot(Bucket bucket, ResourceModel resourceModel) { + Snapshot parentSnapshot = (bucket.getParent() != null ? bucket.getParent().getSnapshot() : null); + Snapshot snapshot = new Snapshot(resourceModel, parentSnapshot); + return snapshot; + } + + @Override + protected void prepareResourceModel(ResourceModel resourceModel, Bucket bucket) { + resourceModel.setRootId(bucket.getProject() != null ? bucket.getProject().getResourceId() : null); + } + + @Override + protected String generateEffectiveKey(Bucket bucket) { + return new StringBuilder(ResourceModel.KEY_SIZE) + .append(bucket.getProject().getResource().getKey()) + .append(':') + .append(bucket.getResource().getKey()) + .toString(); + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/indexer/DefaultSonarIndex.java b/sonar-batch/src/main/java/org/sonar/batch/indexer/DefaultSonarIndex.java new file mode 100644 index 00000000000..48a6bc72997 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/indexer/DefaultSonarIndex.java @@ -0,0 +1,465 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch.indexer; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.batch.Event; +import org.sonar.api.batch.SonarIndex; +import org.sonar.api.database.DatabaseSession; +import org.sonar.jpa.dao.MeasuresDao; +import org.sonar.api.database.model.MeasureModel; +import org.sonar.api.database.model.ResourceModel; +import org.sonar.api.database.model.Snapshot; +import org.sonar.api.database.model.SnapshotSource; +import org.sonar.api.design.Dependency; +import org.sonar.api.design.DependencyDto; +import org.sonar.api.measures.Measure; +import org.sonar.api.measures.MeasuresFilter; +import org.sonar.api.measures.MeasuresFilters; +import org.sonar.api.measures.Metric; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.ProjectLink; +import org.sonar.api.resources.Resource; +import org.sonar.api.resources.ResourceUtils; +import org.sonar.api.rules.Violation; +import org.sonar.batch.ProjectTree; +import org.sonar.batch.ResourceFilters; +import org.sonar.batch.ViolationFilters; +import org.sonar.batch.ViolationsDao; + +import java.util.*; + +public class DefaultSonarIndex extends SonarIndex { + + private static final Logger LOG = LoggerFactory.getLogger(DefaultSonarIndex.class); + + private DatabaseSession session; + private ResourcePersisters resourcePersisters; + private Bucket<Project> rootProjectBucket; + private Bucket<Project> selectedProjectBucket; + + private ViolationFilters violationFilters; + private ResourceFilters resourceFilters; + + // data + private Map<Resource, Bucket> buckets = Maps.newHashMap(); + private Set<Dependency> dependencies = Sets.newHashSet(); + private Map<Resource, Map<Resource, Dependency>> outgoingDependenciesByResource = new HashMap<Resource, Map<Resource, Dependency>>(); + private Map<Resource, Map<Resource, Dependency>> incomingDependenciesByResource = new HashMap<Resource, Map<Resource, Dependency>>(); + + // dao + private ViolationsDao violationsDao; + private MeasuresDao measuresDao; + private ProjectTree projectTree; + + public DefaultSonarIndex(DatabaseSession session, ProjectTree projectTree) { + this.session = session; + this.projectTree = projectTree; + this.resourcePersisters = new ResourcePersisters(session); + } + + public void start() { + Project rootProject = projectTree.getRootProject(); + + this.rootProjectBucket = new Bucket<Project>(rootProject); + persist(rootProjectBucket); + this.buckets.put(rootProject, rootProjectBucket); + this.selectedProjectBucket = rootProjectBucket; + + for (Project project : rootProject.getModules()) { + addProject(project); + } + session.commit(); + } + + private void addProject(Project project) { + addResource(project); + for (Project module : project.getModules()) { + addProject(module); + } + } + + + public void selectProject(Project project, ResourceFilters resourceFilters, ViolationFilters violationFilters, MeasuresDao measuresDao, ViolationsDao violationsDao) { + this.selectedProjectBucket = buckets.get(project); + this.resourceFilters = resourceFilters; + this.violationFilters = violationFilters; + this.violationsDao = violationsDao; + this.measuresDao = measuresDao; + } + + /** + * Keep only project stuff + */ + public void clear() { + Iterator<Map.Entry<Resource, Bucket>> it = buckets.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry<Resource, Bucket> entry = it.next(); + Resource resource = entry.getKey(); + if (!ResourceUtils.isSet(resource)) { + entry.getValue().clear(); + it.remove(); + } + } + + Set<Dependency> projectDependencies = getDependenciesBetweenProjects(); + dependencies.clear(); + incomingDependenciesByResource.clear(); + outgoingDependenciesByResource.clear(); + for (Dependency projectDependency : projectDependencies) { + projectDependency.setId(null); + registerDependency(projectDependency); + } + } + + /* ------------ RESOURCES */ + public Project getRootProject() { + return rootProjectBucket.getResource(); + } + + public Project getProject() { + return selectedProjectBucket.getResource(); + } + + public Bucket getBucket(Resource resource) { + return buckets.get(resource); + } + + public Resource getResource(Resource resource) { + Bucket bucket = buckets.get(resource); + if (bucket != null) { + return bucket.getResource(); + } + return null; + } + + public List<Resource> getChildren(Resource resource) { + List<Resource> children = Lists.newArrayList(); + Bucket<?> bucket = buckets.get(resource); + if (bucket != null) { + for (Bucket childBucket : bucket.getChildren()) { + children.add(childBucket.getResource()); + } + } + return children; + } + + public Resource addResource(Resource resource) { + return getOrCreateBucket(resource).getResource(); + } + + private Bucket<Resource> getOrCreateBucket(Resource resource) { + Bucket bucket = buckets.get(resource); + if (bucket != null) { + return bucket; + } + + prepareResource(resource); + bucket = new Bucket<Resource>(resource); + buckets.put(resource, bucket); + + Bucket parentBucket = null; + Resource parent = resource.getParent(); + if (parent != null) { + parentBucket = getOrCreateBucket(parent); + } else if (!ResourceUtils.isLibrary(resource)) { + parentBucket = selectedProjectBucket; + } + bucket.setParent(parentBucket); + bucket.setProject(selectedProjectBucket); + + persist(bucket); + return bucket; + } + + private void prepareResource(Resource resource) { + resource.setExcluded(resourceFilters != null && resourceFilters.isExcluded(resource)); + } + + private void persist(Bucket bucket) { + resourcePersisters.get(bucket).persist(bucket); + } + + /* ------------ MEASURES */ + public Measure getMeasure(Resource resource, Metric metric) { + return getOrCreateBucket(resource).getMeasures(MeasuresFilters.metric(metric)); + } + + public <M> M getMeasures(Resource resource, MeasuresFilter<M> filter) { + return getOrCreateBucket(resource).getMeasures(filter); + } + + + /* ------------ SOURCE CODE */ + + public void setSource(Resource resource, String source) { + Bucket bucket = getOrCreateBucket(resource); + + if (!bucket.isExcluded()) { + if (bucket.isSourceSaved()) { + LOG.warn("Trying to save twice the source of " + resource); + + } else { + session.save(new SnapshotSource(bucket.getSnapshotId(), source)); + bucket.setSourceSaved(true); + } + } + } + + + /* ------------ RULE VIOLATIONS */ + + public void addViolation(Violation violation) { + Bucket bucket; + Resource resource = violation.getResource(); + if (resource == null) { + bucket = selectedProjectBucket; + } else { + bucket = getOrCreateBucket(resource); + } + if (!bucket.isExcluded()) { + persistViolation(violation, bucket.getSnapshot()); + } + } + + private void persistViolation(Violation violation, Snapshot snapshot) { + boolean isIgnored = violationFilters != null && violationFilters.isIgnored(violation); + if (!isIgnored) { + violationsDao.saveViolation(snapshot, violation); + } + } + + + /* ------------ MEASURES */ + public Measure saveMeasure(Resource resource, Measure measure) { + if (measure.getId() == null) { + return addMeasure(resource, measure); + } + return updateMeasure(measure); + } + + public Measure addMeasure(Resource resource, Measure measure) { + Bucket bucket = getOrCreateBucket(resource); + if (!bucket.isExcluded()) { + if (bucket.getMeasures(MeasuresFilters.measure(measure))!=null) { + throw new IllegalArgumentException("This measure has already been saved: " + measure + ",resource: " + resource); + } + if (shouldPersistMeasure(resource, measure)) { + persistMeasure(bucket, measure); + } + + if (measure.getPersistenceMode().useMemory()) { + bucket.addMeasure(measure); + } + } + return measure; + } + + public Measure updateMeasure(Measure measure) { + if (measure.getId() == null) { + throw new IllegalStateException("Measure can not be updated because it has never been saved"); + } + + MeasureModel model = session.reattach(MeasureModel.class, measure.getId()); + model = MeasureModel.build(measure, model); + model.setMetric(measuresDao.getMetric(measure.getMetric())); + model.save(session); + return measure; + } + + private void persistMeasure(Bucket bucket, Measure measure) { + Metric metric = measuresDao.getMetric(measure.getMetric()); + MeasureModel measureModel = MeasureModel.build(measure); + measureModel.setMetric(metric); // hibernate synchronized metric + measureModel.setSnapshotId(bucket.getSnapshotId()); + measureModel.save(session); + + // the id is saved for future updates + measure.setId(measureModel.getId()); + } + + private boolean shouldPersistMeasure(Resource resource, Measure measure) { + Metric metric = measure.getMetric(); + return measure.getPersistenceMode().useDatabase() && !( + ResourceUtils.isEntity(resource) && + metric.isOptimizedBestValue() == Boolean.TRUE && + metric.getBestValue() != null && + metric.getBestValue().equals(measure.getValue()) && + !measure.hasOptionalData()); + } + + + /* --------------- DEPENDENCIES */ + public Dependency saveDependency(Dependency dependency) { + Dependency persistedDep = getEdge(dependency.getFrom(), dependency.getTo()); + if (persistedDep != null && persistedDep.getId()!=null) { + return persistedDep; + } + Bucket from = getOrCreateBucket(dependency.getFrom()); + Bucket to = getOrCreateBucket(dependency.getTo()); + + DependencyDto dto = new DependencyDto(); + dto.setFromResourceId(from.getResourceId()); + dto.setFromScope(from.getResource().getScope()); + dto.setFromSnapshotId(from.getSnapshotId()); + dto.setToResourceId(to.getResourceId()); + dto.setToSnapshotId(to.getSnapshotId()); + dto.setToScope(to.getResource().getScope()); + dto.setProjectSnapshotId(selectedProjectBucket.getSnapshotId()); + dto.setUsage(dependency.getUsage()); + dto.setWeight(dependency.getWeight()); + + Dependency parentDependency = dependency.getParent(); + if (parentDependency != null) { + saveDependency(parentDependency); + dto.setParentDependencyId(parentDependency.getId()); + } + session.save(dto); + dependency.setId(dto.getId()); + registerDependency(dependency); + + return dependency; + } + + protected void registerDependency(Dependency dependency) { + dependencies.add(dependency); + registerOutgoingDependency(dependency); + registerIncomingDependency(dependency); + } + + private void registerOutgoingDependency(Dependency dependency) { + Map<Resource, Dependency> outgoingDeps = outgoingDependenciesByResource.get(dependency.getFrom()); + if (outgoingDeps == null) { + outgoingDeps = new HashMap<Resource, Dependency>(); + outgoingDependenciesByResource.put(dependency.getFrom(), outgoingDeps); + } + outgoingDeps.put(dependency.getTo(), dependency); + } + + private void registerIncomingDependency(Dependency dependency) { + Map<Resource, Dependency> incomingDeps = incomingDependenciesByResource.get(dependency.getTo()); + if (incomingDeps == null) { + incomingDeps = new HashMap<Resource, Dependency>(); + incomingDependenciesByResource.put(dependency.getTo(), incomingDeps); + } + incomingDeps.put(dependency.getFrom(), dependency); + } + + public Set<Dependency> getDependencies() { + return dependencies; + } + + + /* ------------ LINKS */ + + public void saveLink(ProjectLink link) { + ResourceModel projectDao = session.reattach(ResourceModel.class, selectedProjectBucket.getResourceId()); + ProjectLink dbLink = projectDao.getProjectLink(link.getKey()); + if (dbLink == null) { + link.setResource(projectDao); + projectDao.getProjectLinks().add(link); + session.save(link); + + } else { + dbLink.copyFieldsFrom(link); + session.save(dbLink); + } + } + + public void deleteLink(String key) { + ResourceModel projectDao = session.reattach(ResourceModel.class, selectedProjectBucket.getResourceId()); + ProjectLink dbLink = projectDao.getProjectLink(key); + if (dbLink != null) { + session.remove(dbLink); + projectDao.getProjectLinks().remove(dbLink); + } + } + + + /* ----------- EVENTS */ + public List<Event> getEvents(Resource resource) { + Bucket bucket = getOrCreateBucket(resource); + return session.getResults(Event.class, "resourceId", bucket.getResourceId()); + } + + public void deleteEvent(Event event) { + session.remove(event); + } + + public Event createEvent(Resource resource, String name, String description, String category, Date date) { + Bucket bucket = getOrCreateBucket(resource); + Event event; + if (date == null) { + event = new Event(name, description, category, bucket.getSnapshot()); + } else { + event = new Event(name, description, category, date, bucket.getResourceId()); + } + return session.save(event); + } + + public Dependency getEdge(Resource from, Resource to) { + Map<Resource, Dependency> map = outgoingDependenciesByResource.get(from); + if (map != null) { + return map.get(to); + } + return null; + } + + public boolean hasEdge(Resource from, Resource to) { + return getEdge(from, to) != null; + } + + public Set<Resource> getVertices() { + return buckets.keySet(); + } + + public Collection<Dependency> getOutgoingEdges(Resource from) { + Map<Resource, Dependency> deps = outgoingDependenciesByResource.get(from); + if (deps != null) { + return deps.values(); + } + return Collections.emptyList(); + } + + public Collection<Dependency> getIncomingEdges(Resource to) { + Map<Resource, Dependency> deps = incomingDependenciesByResource.get(to); + if (deps != null) { + return deps.values(); + } + return Collections.emptyList(); + } + + public Set<Dependency> getDependenciesBetweenProjects() { + Set<Dependency> result = new HashSet<Dependency>(); + for (Project project : projectTree.getProjects()) { + Collection<Dependency> deps = getOutgoingDependencies(project); + for (Dependency dep : deps) { + if (ResourceUtils.isSet(dep.getTo())) { + result.add(dep); + } + } + } + return result; + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/indexer/LibraryPersister.java b/sonar-batch/src/main/java/org/sonar/batch/indexer/LibraryPersister.java new file mode 100644 index 00000000000..640997e2f8f --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/indexer/LibraryPersister.java @@ -0,0 +1,68 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch.indexer; + +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.model.ResourceModel; +import org.sonar.api.database.model.Snapshot; +import org.sonar.api.resources.Library; +import org.sonar.api.resources.Resource; + +import java.util.Date; + +public class LibraryPersister extends ResourcePersister<Library> { + + private Date now; + + public LibraryPersister(DatabaseSession session) { + super(session); + this.now = new Date(); + } + + LibraryPersister(DatabaseSession session, Date now) { + super(session); + this.now = now; + } + + @Override + protected String generateEffectiveKey(Bucket<Library> bucket) { + return bucket.getResource().getKey(); + } + + @Override + protected void prepareResourceModel(ResourceModel resourceModel, Bucket<Library> bucket) { + } + + @Override + protected Snapshot createSnapshot(Bucket<Library> bucket, ResourceModel resourceModel) { + Snapshot snapshot = getSession().getSingleResult(Snapshot.class, + "resourceId", resourceModel.getId(), + "version", bucket.getResource().getVersion(), + "scope", Resource.SCOPE_SET, + "qualifier", Resource.QUALIFIER_LIB); + if (snapshot == null) { + snapshot = new Snapshot(resourceModel, null); + snapshot.setCreatedAt(now); + snapshot.setVersion(bucket.getResource().getVersion()); + snapshot.setStatus(Snapshot.STATUS_PROCESSED); + } + return snapshot; + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/indexer/ProjectPersister.java b/sonar-batch/src/main/java/org/sonar/batch/indexer/ProjectPersister.java new file mode 100644 index 00000000000..821910b4538 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/indexer/ProjectPersister.java @@ -0,0 +1,58 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch.indexer; + +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.model.ResourceModel; +import org.sonar.api.database.model.Snapshot; +import org.sonar.api.resources.Project; + +public class ProjectPersister extends ResourcePersister<Project> { + + public ProjectPersister(DatabaseSession session) { + super(session); + } + + @Override + protected String generateEffectiveKey(Bucket<Project> bucket) { + return bucket.getResource().getKey(); + } + + @Override + protected void prepareResourceModel(ResourceModel resourceModel, Bucket<Project> bucket) { + if (bucket.getProject() != null) { + resourceModel.setRootId(bucket.getProject().getResourceId()); + } + + // LIMITATION : project.getLanguage() is set only in ProjectBatch, not in AggregatorBatch, so we + // have to explicitely use project.getLanguageKey() + resourceModel.setLanguageKey(bucket.getResource().getLanguageKey()); + } + + @Override + protected Snapshot createSnapshot(Bucket<Project> bucket, ResourceModel resourceModel) { + Project project = bucket.getResource(); + Snapshot parentSnapshot = (bucket.getParent() != null ? bucket.getParent().getSnapshot() : null); + Snapshot snapshot = new Snapshot(resourceModel, parentSnapshot); + snapshot.setVersion(project.getAnalysisVersion()); + snapshot.setCreatedAt(project.getAnalysisDate()); + return snapshot; + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/indexer/ResourcePersister.java b/sonar-batch/src/main/java/org/sonar/batch/indexer/ResourcePersister.java new file mode 100644 index 00000000000..6ad3be1344d --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/indexer/ResourcePersister.java @@ -0,0 +1,96 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch.indexer; + +import javax.persistence.NonUniqueResultException; + +import org.apache.commons.lang.StringUtils; +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.database.model.ResourceModel; +import org.sonar.api.database.model.Snapshot; +import org.sonar.api.resources.Resource; +import org.sonar.api.resources.ResourceUtils; +import org.sonar.api.utils.SonarException; + +public abstract class ResourcePersister<RESOURCE extends Resource> { + + private DatabaseSession session; + + public ResourcePersister(DatabaseSession session) { + this.session = session; + } + + protected DatabaseSession getSession() { + return session; + } + + public final void persist(Bucket<RESOURCE> bucket) { + String effectiveKey = generateEffectiveKey(bucket); + ResourceModel model; + try { + model = session.getSingleResult(ResourceModel.class, "key", effectiveKey); + } catch (NonUniqueResultException e) { + throw new SonarException("The resource '" + effectiveKey + "' is duplicated in the Sonar DB."); + } + + RESOURCE resource = bucket.getResource(); + if (model == null) { + model = ResourceModel.build(resource); + model.setKey(effectiveKey); + + } else { + // update existing record + model.setEnabled(true); + if (StringUtils.isNotBlank(resource.getName())) { + model.setName(resource.getName()); + } + if (StringUtils.isNotBlank(resource.getLongName())) { + model.setLongName(resource.getLongName()); + } + if (StringUtils.isNotBlank(resource.getDescription())) { + model.setDescription(resource.getDescription()); + } + if ( !ResourceUtils.isLibrary(resource)) { + model.setScope(resource.getScope()); + model.setQualifier(resource.getQualifier()); + } + if (resource.getLanguage() != null) { + model.setLanguageKey(resource.getLanguage().getKey()); + } + } + + prepareResourceModel(model, bucket); + model = session.save(model); + resource.setId(model.getId()); + resource.setEffectiveKey(model.getKey()); + + Snapshot snapshot = createSnapshot(bucket, model); + if (snapshot.getId() == null) { + session.save(snapshot); + } + bucket.setSnapshot(snapshot); + } + + protected abstract void prepareResourceModel(ResourceModel resourceModel, Bucket<RESOURCE> bucket); + + protected abstract Snapshot createSnapshot(Bucket<RESOURCE> bucket, ResourceModel resourceModel); + + protected abstract String generateEffectiveKey(Bucket<RESOURCE> bucket); +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/indexer/ResourcePersisters.java b/sonar-batch/src/main/java/org/sonar/batch/indexer/ResourcePersisters.java new file mode 100644 index 00000000000..f359a0ae623 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/indexer/ResourcePersisters.java @@ -0,0 +1,50 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch.indexer; + +import org.sonar.api.database.DatabaseSession; +import org.sonar.api.resources.Library; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.Resource; + +import java.util.HashMap; +import java.util.Map; + +public final class ResourcePersisters { + + private Map<Class<? extends Resource>, ResourcePersister> persistersByClass; + private ResourcePersister defaultPersister; + + public ResourcePersisters(DatabaseSession session) { + defaultPersister = new DefaultPersister(session); + persistersByClass = new HashMap<Class<? extends Resource>, ResourcePersister>(); + persistersByClass.put(Project.class, new ProjectPersister(session)); + persistersByClass.put(Library.class, new LibraryPersister(session)); + } + + public ResourcePersister get(Bucket bucket) { + return get(bucket.getResource()); + } + + public ResourcePersister get(Resource resource) { + ResourcePersister persister = persistersByClass.get(resource.getClass()); + return persister != null ? persister : defaultPersister; + } +} diff --git a/sonar-batch/src/main/resources/org/sonar/batch/logback.xml b/sonar-batch/src/main/resources/org/sonar/batch/logback.xml new file mode 100644 index 00000000000..cd79fb299d6 --- /dev/null +++ b/sonar-batch/src/main/resources/org/sonar/batch/logback.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8" ?> + +<configuration debug="false"> + + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + <layout class="ch.qos.logback.classic.PatternLayout"> + <pattern>[%level] %X{module} %msg%n</pattern> + </layout> + </appender> + + <logger name="org.hibernate"> + <level value="WARN"/> + </logger> + + <!-- set INFO to activate SQL logs. NOT RECOMMENDED --> + <logger name="org.hibernate.SQL"> + <level value="ERROR"/> + </logger> + + <!-- set INFO to activate SQL statistics. NOT RECOMMENDED --> + <logger name="org.sonar.DBSTATISTICS"> + <level value="ERROR"/> + </logger> + + <logger name="net.sf.ehcache"> + <level value="WARN"/> + </logger> + + <logger name="org.hibernate.cache.ReadWriteCache"> + <!-- removing "An item was expired by the cache while it was locked (increase your cache timeout)" msg --> + <level value="ERROR"/> + </logger> + <logger name="org.hibernate.cache.EhCacheProvider"> + <!-- removing "org.hibernate.cache.EhCacheProvider - Could not find configuratio)" message --> + <level value="ERROR"/> + </logger> + + <!-- see org.sonar.mojo.InternalMojo#initLogging --> + <root> + <level value="${ROOT_LOGGER_LEVEL}"/> + <appender-ref ref="STDOUT"/> + </root> + +</configuration>
\ No newline at end of file diff --git a/sonar-batch/src/test/java/org/sonar/batch/CoreJobsTest.java b/sonar-batch/src/test/java/org/sonar/batch/CoreJobsTest.java new file mode 100644 index 00000000000..25c2e046e47 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/CoreJobsTest.java @@ -0,0 +1,29 @@ +package org.sonar.batch; + +import static org.hamcrest.Matchers.greaterThan; +import static org.junit.Assert.assertThat; +import org.junit.Test; + +import java.util.List; + +public class CoreJobsTest { + + @Test + public void mavenPluginsAreExecutedAfterBeingConfigured() { + List<Class<? extends CoreJob>> jobs = CoreJobs.allJobs(); + assertThat(jobs.indexOf(FinalizeSnapshotsJob.class), + greaterThan(jobs.indexOf(DecoratorsExecutor.class))); + } + + @Test + public void finalizeJobIsExecutedAfterDecorators() { + List<Class<? extends CoreJob>> jobs = CoreJobs.allJobs(); + assertThat(jobs.indexOf(FinalizeSnapshotsJob.class), + greaterThan(jobs.indexOf(DecoratorsExecutor.class))); + } + + @Test + public void allJobs() { + assertThat(CoreJobs.allJobs().size(), greaterThan(3)); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/DecoratorsSelectorTest.java b/sonar-batch/src/test/java/org/sonar/batch/DecoratorsSelectorTest.java new file mode 100644 index 00000000000..90edc924f10 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/DecoratorsSelectorTest.java @@ -0,0 +1,114 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import org.junit.Test; +import static org.junit.internal.matchers.IsCollectionContaining.hasItem; +import static org.mockito.Mockito.mock; +import org.picocontainer.containers.TransientPicoContainer; +import org.sonar.api.batch.*; +import org.sonar.api.measures.*; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.Resource; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +public class DecoratorsSelectorTest { + + private Metric withFormula1 = new Metric("metric1").setFormula(new FakeFormula()); + private Metric withFormula2 = new Metric("metric2").setFormula(new FakeFormula()); + private Metric withoutFormula = new Metric("metric3"); + + @Test + public void selectAndSortFormulas() { + Project project = new Project("key"); + BatchExtensionDictionnary dictionnary = newDictionnary(withFormula1, withoutFormula, withFormula2); + + Collection<Decorator> decorators = new DecoratorsSelector(dictionnary).select(project); + assertThat(decorators.size(), is(2)); + assertThat(decorators, hasItem((Decorator) new FormulaDecorator(withFormula1))); + assertThat(decorators, hasItem((Decorator) new FormulaDecorator(withFormula2))); + } + + @Test + public void pluginDecoratorsCanOverrideFormulas() { + Project project = new Project("key"); + Decorator fakeDecorator = new FakeDecorator(); + Decorator metric1Decorator = new Metric1Decorator(); + BatchExtensionDictionnary dictionnary = newDictionnary(fakeDecorator, metric1Decorator, withFormula1, withoutFormula, withFormula2); + + Collection<Decorator> decorators = new DecoratorsSelector(dictionnary).select(project); + + assertThat(decorators.size(), is(3)); + assertThat(decorators, hasItem(fakeDecorator)); + assertThat(decorators, hasItem(metric1Decorator)); + assertThat(decorators, hasItem((Decorator) new FormulaDecorator(withFormula2))); + } + + private BatchExtensionDictionnary newDictionnary(Object... extensions) { + TransientPicoContainer ioc = new TransientPicoContainer(); + int index = 0; + for (Object extension : extensions) { + ioc.addComponent("" + index, extension); + index++; + } + return new BatchExtensionDictionnary(ioc); + } + + + class FakeFormula implements Formula { + public List<Metric> dependsUponMetrics() { + return Arrays.asList(); + } + + public Measure calculate(FormulaData data, FormulaContext context) { + return null; + } + } + + public class Metric1Decorator implements Decorator { + @DependedUpon + public Metric generatesMetric1Measure() { + return withFormula1; + } + + public void decorate(Resource resource, DecoratorContext context) { + + } + + public boolean shouldExecuteOnProject(Project project) { + return true; + } + } + + public class FakeDecorator implements Decorator { + public void decorate(Resource resource, DecoratorContext context) { + + } + + public boolean shouldExecuteOnProject(Project project) { + return true; + } + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/DefaultSensorContextTest.java b/sonar-batch/src/test/java/org/sonar/batch/DefaultSensorContextTest.java new file mode 100644 index 00000000000..dba2db3e375 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/DefaultSensorContextTest.java @@ -0,0 +1,244 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.sonar.api.database.model.Snapshot; +import org.sonar.api.design.Dependency; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Measure; +import org.sonar.api.measures.PersistenceMode; +import org.sonar.api.measures.RuleMeasure; +import org.sonar.api.resources.JavaFile; +import org.sonar.api.resources.JavaPackage; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.Resource; +import org.sonar.api.rules.RulePriority; +import org.sonar.jpa.test.AbstractDbUnitTestCase; + +import javax.persistence.Query; +import java.text.ParseException; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.core.IsNot.not; +import static org.junit.Assert.assertThat; + +@Ignore +public class DefaultSensorContextTest extends AbstractDbUnitTestCase { + private DefaultSensorContext context; + private Project project; + + @Before + public void before() { + project = null; + context = null; + } + + @Test + public void saveProjectMeasure() throws ParseException { + setup("saveProjectMeasure"); + context.saveMeasure(CoreMetrics.NCLOC, 500.0); + check("saveProjectMeasure", "projects", "snapshots", "project_measures"); + } + + @Test + public void saveMeasureOnExistingResource() throws ParseException { + setup("saveMeasureOnExistingResource"); + context.saveMeasure(new JavaPackage("org.sonar"), CoreMetrics.NCLOC, 200.0); + check("saveMeasureOnExistingResource", "projects", "snapshots", "project_measures"); + } + + @Test + public void avoidConflictWithResourceFromOtherProject() throws ParseException { + setup("avoidConflictWithResourceFromOtherProject"); + context.saveMeasure(new JavaPackage("org.sonar"), CoreMetrics.NCLOC, 200.0); + context.saveMeasure(new JavaPackage("org.sonar"), CoreMetrics.COVERAGE, 80.0); + check("avoidConflictWithResourceFromOtherProject", "projects", "snapshots", "project_measures"); + } + + @Test + public void doNotPersistInMemoryMeasures() throws ParseException { + setup("doNotPersistInMemoryMeasures"); + Measure measure = new Measure(CoreMetrics.NCLOC, 30.0).setPersistenceMode(PersistenceMode.MEMORY); + context.saveMeasure(measure); + + check("doNotPersistInMemoryMeasures", "projects", "snapshots", "project_measures"); + assertThat(context.getMeasure(CoreMetrics.NCLOC).getValue(), is(30.0)); + } + + @Test + public void doNotCacheDatabaseMeasures() throws ParseException { + setup("doNotCacheDatabaseMeasures"); + Measure measure = new Measure(CoreMetrics.NCLOC, 500.0).setPersistenceMode(PersistenceMode.DATABASE); + context.saveMeasure(measure); + + check("doNotCacheDatabaseMeasures", "projects", "snapshots", "project_measures"); + assertThat(context.getMeasure(CoreMetrics.NCLOC), nullValue()); + } + + @Test + public void saveRuleMeasures() throws ParseException { + setup("saveRuleMeasures"); + context.saveMeasure(RuleMeasure.createForPriority(CoreMetrics.VIOLATIONS, RulePriority.CRITICAL, 500.0)); + context.saveMeasure(RuleMeasure.createForCategory(CoreMetrics.VIOLATIONS, 3, 200.0)); + //FIXME context.saveMeasure(RuleMeasure.createForRule(CoreMetrics.VIOLATIONS, 3).setIntValue(50.0)); + check("saveRuleMeasures", "projects", "snapshots", "project_measures"); + } + + @Test + public void saveResourceTree() throws ParseException { +// setup("saveResourceTree"); +// +// assertThat(context.getResource("org.foo.Bar"), nullValue()); +// context.saveResource(new JavaFile("org.foo.Bar")); +// assertThat(context.getResource("org.foo.Bar"), is((Resource) new JavaFile("org.foo.Bar"))); +// +// check("saveResourceTree", "projects", "snapshots"); + } +// +// @Test +// public void doNotSaveExcludedResources() throws ParseException { +// setup("doNotSaveExcludedResources"); +// +// JavaFile javaFile = new JavaFile("org.excluded.Bar"); +// ResourceFilters resourceFilters = mock(ResourceFilters.class); +// when(resourceFilters.isExcluded(javaFile)).thenReturn(true); +// context.setResourceFilters(resourceFilters); +// +// assertThat(context.getResource("org.excluded.Bar"), nullValue()); +// assertThat(context.saveResource(javaFile), nullValue()); +// assertThat(context.getResource("org.excluded.Bar"), nullValue()); +// +// check("doNotSaveExcludedResources", "projects", "snapshots"); +// } + + @Test + public void updateExistingResourceFields() throws ParseException { + setup("updateExistingResourceFields"); + + context.saveResource(new JavaPackage("org.foo")); + + check("updateExistingResourceFields", "projects", "snapshots"); + } + + @Test + public void doNotSaveOptimizedBestValues() throws ParseException { + setup("doNotSaveOptimizedBestValues"); + + // best values of the metrics violations and blocker_violations are set as optimized + assertThat(CoreMetrics.VIOLATIONS.getBestValue(), is(0.0)); + assertThat(CoreMetrics.BLOCKER_VIOLATIONS.getBestValue(), is(0.0)); + assertThat(CoreMetrics.VIOLATIONS.isOptimizedBestValue(), is(true)); + assertThat(CoreMetrics.BLOCKER_VIOLATIONS.isOptimizedBestValue(), is(true)); + + final Resource javaFile = new JavaFile("org.foo.Bar"); + assertThat(context.getMeasure(javaFile, CoreMetrics.VIOLATIONS), nullValue()); + context.saveMeasure(javaFile, CoreMetrics.VIOLATIONS, 60.0); // saved + assertThat(context.getMeasure(javaFile, CoreMetrics.VIOLATIONS).getValue(), is(60.0)); + + assertThat(context.getMeasure(javaFile, CoreMetrics.BLOCKER_VIOLATIONS), nullValue()); + context.saveMeasure(javaFile, CoreMetrics.BLOCKER_VIOLATIONS, 0.0); // not saved in database + assertThat(context.getMeasure(javaFile, CoreMetrics.BLOCKER_VIOLATIONS).getValue(), is(0.0)); + + check("doNotSaveOptimizedBestValues", "projects", "snapshots", "project_measures"); + } + + @Test + public void saveOptimizedBestValuesIfOptionalFields() throws ParseException { + setup("saveOptimizedBestValuesIfOptionalFields"); + + // best value of the metric violations is set as optimized + assertThat(CoreMetrics.VIOLATIONS.getBestValue(), is(0.0)); + assertThat(CoreMetrics.VIOLATIONS.isOptimizedBestValue(), is(true)); + + final Resource javaFile = new JavaFile("org.foo.Bar"); + assertThat(context.getMeasure(javaFile, CoreMetrics.VIOLATIONS), nullValue()); + Measure measure = new Measure(CoreMetrics.VIOLATIONS, 0.0).setTendency(1); + + context.saveMeasure(javaFile, measure); // saved + + assertThat(context.getMeasure(javaFile, CoreMetrics.VIOLATIONS).getValue(), is(0.0)); + assertThat(context.getMeasure(javaFile, CoreMetrics.VIOLATIONS).getTendency(), is(1)); + + check("saveOptimizedBestValuesIfOptionalFields", "projects", "snapshots", "project_measures"); + } + + + @Test + public void saveDependency() throws ParseException { + setup("saveDependency"); + + JavaPackage pac1 = new JavaPackage("org.sonar.source"); + JavaPackage pac2 = new JavaPackage("org.sonar.target"); + context.saveResource(pac1); + context.saveResource(pac2); + + Dependency dep = new Dependency(pac1, pac2) + .setUsage("INHERITS") + .setWeight(3); + context.saveDependency(dep); + + assertThat(dep.getId(), not(nullValue())); + + check("saveDependency", "projects", "snapshots", "dependencies"); + } + + @Test(expected = IllegalArgumentException.class) + public void saveResourcesBeforeBuildingDependencies() throws ParseException { + setup("saveResourcesBeforeBuildingDependencies"); + + JavaPackage pac1 = new JavaPackage("org.sonar.source"); + JavaPackage pac2 = new JavaPackage("org.sonar.target"); + context.saveDependency(new Dependency(pac1, pac2)); + } + + + private void setup(String unitTest) throws ParseException { +// setupData(unitTest); +// project = mock(Project.class); +// when(project.getAnalysisVersion()).thenReturn("1.0"); +// when(project.getAnalysisDate()).thenReturn(new SimpleDateFormat("yyyy-MM-dd").parse("2008-12-25")); +// when(project.getKey()).thenReturn("group:artifact"); +// when(project.getScope()).thenReturn(Resource.SCOPE_SET); +// when(project.getQualifier()).thenReturn(Resource.QUALIFIER_PROJECT); +// when(project.getLanguage()).thenReturn(Java.INSTANCE); +// when(project.getId()).thenReturn(10); +// when(project.getName()).thenReturn("my project"); +// when(project.isRoot()).thenReturn(true); +// ProjectBootstrap projectBootstrap = new ProjectBootstrap(null); +// projectBootstrap.setProject(project); +// projectBootstrap.setSnapshot(getSnapshot(1)); +// context = new DefaultSensorContext(getSession(), projectBootstrap.setProject(project), getDao().getMeasuresDao(), null, null, null); + } + + private void check(String unitTest, String... tables) { + getSession().commit(); + checkTables(unitTest, tables); + } + + private Snapshot getSnapshot(int id) { + Query query = getSession().createQuery("SELECT s FROM Snapshot s WHERE s.id=:id"); + query.setParameter("id", id); + return (Snapshot) query.getSingleResult(); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/DefaultTimeMachineTest.java b/sonar-batch/src/test/java/org/sonar/batch/DefaultTimeMachineTest.java new file mode 100644 index 00000000000..8e097ddccc3 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/DefaultTimeMachineTest.java @@ -0,0 +1,108 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.junit.Test; +import org.sonar.api.batch.TimeMachineQuery; +import org.sonar.jpa.dao.MeasuresDao; +import org.sonar.jpa.test.AbstractDbUnitTestCase; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.api.measures.Measure; +import org.sonar.api.resources.Project; +import org.sonar.api.resources.Resource; +import org.sonar.batch.indexer.DefaultSonarIndex; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.number.OrderingComparisons.greaterThan; +import static org.junit.Assert.assertThat; +import static org.mockito.Matchers.anyObject; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class DefaultTimeMachineTest extends AbstractDbUnitTestCase { + + @Test(timeout = 3000) + public void loadMeasureFieldsFromDate() throws ParseException { + setupData("loadMeasuresFromDate"); + DefaultTimeMachine timeMachine = initTimeMachine(); + + TimeMachineQuery query = new TimeMachineQuery(null).setFrom(date("2008-02-01")).setMetrics(Arrays.asList(CoreMetrics.NCLOC)); + List<Object[]> measures = timeMachine.getMeasuresFields(query); + + assertThat(measures.size(), is(3)); + for (Object[] measure : measures) { + assertThat(measure.length, is(3)); // 3 fields + assertThat(measure[1], is((Object) CoreMetrics.NCLOC)); + } + assertThat(measures.get(0)[2], is((Object) 200d)); + assertThat(measures.get(1)[2], is((Object) 230d)); + assertThat(measures.get(2)[2], is((Object) 180d)); + } + + private DefaultTimeMachine initTimeMachine() { + DefaultSonarIndex index = mock(DefaultSonarIndex.class); + when(index.getResource((Resource) anyObject())).thenReturn(new Project("group:artifact").setId(1)); + DefaultTimeMachine timeMachine = new DefaultTimeMachine(getSession(), index, new MeasuresDao(getSession())); + return timeMachine; + } + + @Test(timeout = 3000) + public void loadMeasuresFromDate() throws ParseException { + setupData("loadMeasuresFromDate"); + DefaultTimeMachine timeMachine = initTimeMachine(); + + + TimeMachineQuery query = new TimeMachineQuery(null).setFrom(date("2008-02-01")).setMetrics(Arrays.asList(CoreMetrics.NCLOC)); + List<Measure> measures = timeMachine.getMeasures(query); + + assertThat(measures.size(), is(3)); + long previous = 0; + for (Measure measure : measures) { + assertThat(measure.getMetric(), is(CoreMetrics.NCLOC)); + assertThat(measure.getDate().getTime(), greaterThan(previous)); + previous = measure.getDate().getTime(); + } + assertThat(measures.get(0).getValue(), is(200d)); + assertThat(measures.get(1).getValue(), is(230d)); + assertThat(measures.get(2).getValue(), is(180d)); + } + + @Test(timeout = 3000) + public void loadMeasuresFromDateInterval() throws ParseException { + setupData("loadMeasuresFromDate"); + DefaultTimeMachine timeMachine = initTimeMachine(); + + + TimeMachineQuery query = new TimeMachineQuery(null).setFrom(date("2008-01-01")).setTo(date("2008-12-25")).setMetrics(Arrays.asList(CoreMetrics.NCLOC)); + List<Measure> measures = timeMachine.getMeasures(query); + assertThat(measures.size(), is(1)); + assertThat(measures.get(0).getValue(), is(200d)); + } + + private Date date(String date) throws ParseException { + return new SimpleDateFormat("yyyy-MM-dd").parse(date); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/FinalizeSnapshotsJobTest.java b/sonar-batch/src/test/java/org/sonar/batch/FinalizeSnapshotsJobTest.java new file mode 100644 index 00000000000..9158839ea1a --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/FinalizeSnapshotsJobTest.java @@ -0,0 +1,78 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.junit.Before; +import org.junit.Test; +import org.sonar.api.batch.Purge; +import org.sonar.api.database.model.Snapshot; +import org.sonar.api.resources.Project; +import org.sonar.core.purge.DefaultPurgeContext; +import org.sonar.jpa.test.AbstractDbUnitTestCase; + +import javax.persistence.Query; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +public class FinalizeSnapshotsJobTest extends AbstractDbUnitTestCase { + + private Purge purgeMock=null; + + @Before + public void before() { + purgeMock = mock(Purge.class); + } + + @Test + public void shouldUnflagPenultimateLastSnapshot() throws Exception { + assertAnalysis(11, "shouldUnflagPenultimateLastSnapshot"); + verify(purgeMock).purge(new DefaultPurgeContext(11, 1)); + } + + @Test + public void doNotFailIfNoPenultimateLast() throws Exception { + assertAnalysis(5, "doNotFailIfNoPenultimateLast"); + verify(purgeMock).purge(new DefaultPurgeContext(5, null)); + } + + @Test + public void lastSnapshotIsNotUpdatedWhenAnalyzingPastSnapshot() { + assertAnalysis(6, "lastSnapshotIsNotUpdatedWhenAnalyzingPastSnapshot"); + verify(purgeMock).purge(new DefaultPurgeContext(6, null)); + } + + private void assertAnalysis(int snapshotId, String fixture) { + setupData("sharedFixture", fixture); + + FinalizeSnapshotsJob sensor = new FinalizeSnapshotsJob(mock(ServerMetadata.class), getSession(), new Purge[]{purgeMock}, loadSnapshot(snapshotId)); + sensor.execute(new Project("key"), null); + + getSession().stop(); + checkTables(fixture, "snapshots"); + } + + + private Snapshot loadSnapshot(int id) { + Query query = getSession().createQuery("SELECT s FROM Snapshot s WHERE s.id=:id"); + query.setParameter("id", id); + return (Snapshot) query.getSingleResult(); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/MavenPhaseExecutorTest.java b/sonar-batch/src/test/java/org/sonar/batch/MavenPhaseExecutorTest.java new file mode 100644 index 00000000000..77d1e333e9c --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/MavenPhaseExecutorTest.java @@ -0,0 +1,58 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.apache.commons.configuration.PropertiesConfiguration; +import org.junit.Test; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.resources.Project; + +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.*; + +public class MavenPhaseExecutorTest { + + @Test + public void doNothingIfNoPhase() { + MavenPluginExecutor mavenPluginExecutor = mock(MavenPluginExecutor.class); + MavenPhaseExecutor phaseExecutor = new MavenPhaseExecutor(mavenPluginExecutor); + + + Project project = new Project("key"); + phaseExecutor.execute(project, mock(SensorContext.class)); + + verify(mavenPluginExecutor, never()).execute(eq(project), anyString()); + } + + @Test + public void executePhase() { + MavenPluginExecutor mavenPluginExecutor = mock(MavenPluginExecutor.class); + MavenPhaseExecutor phaseExecutor = new MavenPhaseExecutor(mavenPluginExecutor); + + Project project = new Project("key"); + PropertiesConfiguration conf = new PropertiesConfiguration(); + conf.setProperty(MavenPhaseExecutor.PROP_PHASE, "myphase"); + project.setConfiguration(conf); + + phaseExecutor.execute(project, mock(SensorContext.class)); + + verify(mavenPluginExecutor).execute(project, "myphase"); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/MavenPluginsConfiguratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/MavenPluginsConfiguratorTest.java new file mode 100644 index 00000000000..aea7b42c6cb --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/MavenPluginsConfiguratorTest.java @@ -0,0 +1,77 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; +import org.junit.Test; +import org.sonar.api.batch.BatchExtensionDictionnary; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.batch.maven.MavenPlugin; +import org.sonar.api.batch.maven.MavenPluginHandler; +import org.sonar.api.resources.Project; +import org.sonar.api.test.MavenTestUtils; +import org.sonar.api.utils.ServerHttpClient; + +import java.util.Arrays; + +import static org.mockito.Matchers.argThat; +import static org.mockito.Mockito.*; + +public class MavenPluginsConfiguratorTest { + + private MavenPluginsConfigurator newConfigurator(MavenPluginHandler... handlers) { + BatchExtensionDictionnary selector = mock(BatchExtensionDictionnary.class); + when(selector.selectMavenPluginHandlers((Project) anyObject())).thenReturn(Arrays.asList(handlers)); + return new MavenPluginsConfigurator(selector); + } + + @Test + public void configureHandlers() { + MavenPluginHandler handler1 = mock(MavenPluginHandler.class); + when(handler1.getArtifactId()).thenReturn("myartifact1"); + + MavenPluginHandler handler2 = mock(MavenPluginHandler.class); + when(handler2.getArtifactId()).thenReturn("myartifact2"); + + Project project = MavenTestUtils.loadProjectFromPom(getClass(), "pom.xml"); + + newConfigurator(handler1, handler2).execute(project, mock(SensorContext.class)); + + verify(handler1).configure(eq(project), argThat(new IsMavenPlugin("myartifact1"))); + verify(handler2).configure(eq(project), argThat(new IsMavenPlugin("myartifact2"))); + } + + private class IsMavenPlugin extends BaseMatcher<MavenPlugin> { + private String artifactId; + + public IsMavenPlugin(String artifactId) { + this.artifactId = artifactId; + } + + public boolean matches(Object o) { + return artifactId.equals(((MavenPlugin) o).getPlugin().getArtifactId()); + } + + public void describeTo(Description description) { + + } + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/PostJobsExecutorTest.java b/sonar-batch/src/test/java/org/sonar/batch/PostJobsExecutorTest.java new file mode 100644 index 00000000000..6a1d72cbc58 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/PostJobsExecutorTest.java @@ -0,0 +1,66 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.junit.Test; +import org.sonar.api.batch.PostJob; +import org.sonar.api.batch.SensorContext; +import org.sonar.api.resources.Project; + +import java.util.Arrays; +import java.util.List; + +import static org.mockito.Matchers.anyObject; +import static org.mockito.Mockito.*; + +public class PostJobsExecutorTest { + + @Test + public void doNotExecuteOnModules() { + PostJob job1 = mock(PostJob.class); + Project module = new Project("module").setParent(new Project("project")); + + PostJobsExecutor executor = new PostJobsExecutor(Arrays.<PostJob>asList(job1), mock(MavenPluginExecutor.class)); + executor.execute(module, mock(SensorContext.class)); + + verify(job1, never()).executeOn((Project) anyObject(), (SensorContext) anyObject()); + } + + @Test + public void executeAllPostJobs() { + PostJob job1 = mock(PostJob.class); + PostJob job2 = mock(PostJob.class); + List<PostJob> jobs = Arrays.asList(job1, job2); + + PostJobsExecutor executor = new PostJobsExecutor(jobs, mock(MavenPluginExecutor.class)); + Project project = new Project("project"); + SensorContext context = mock(SensorContext.class); + executor.execute(project, context); + + verify(job1).executeOn(project, context); + verify(job2).executeOn(project, context); + + } + + static class FakePostJob implements PostJob { + public void executeOn(Project project, SensorContext context) { + } + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/ProfileProviderTest.java b/sonar-batch/src/test/java/org/sonar/batch/ProfileProviderTest.java new file mode 100644 index 00000000000..bdefef5c6c8 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/ProfileProviderTest.java @@ -0,0 +1,95 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.apache.commons.configuration.MapConfiguration; +import org.junit.Test; +import org.sonar.jpa.dao.ProfilesDao; +import org.sonar.api.profiles.Alert; +import org.sonar.api.profiles.RulesProfile; +import org.sonar.api.resources.Java; +import org.sonar.api.resources.Project; +import org.sonar.api.rules.ActiveRule; + +import java.util.Collections; +import java.util.HashMap; + +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.*; + +public class ProfileProviderTest { + + @Test + public void shouldGetProjectProfile() { + ProfileProvider provider = new ProfileProvider(); + Project project = new Project("project").setLanguageKey(Java.KEY); + Project module = new Project("module").setParent(project).setLanguageKey(Java.KEY); + ProfilesDao dao = mock(ProfilesDao.class); + + when(dao.getActiveProfile(Java.KEY, "project")).thenReturn(newProfile()); + + assertNotNull(provider.provide(module, dao)); + + verify(dao, never()).getActiveProfile(Java.KEY, "module"); + verify(dao).getActiveProfile(Java.KEY, "project"); + } + + private RulesProfile newProfile() { + RulesProfile profile = new RulesProfile(); + profile.setAlerts(Collections.<Alert>emptyList()); + profile.setActiveRules(Collections.<ActiveRule>emptyList()); + return profile; + } + + @Test + public void mavenPropertyShouldOverrideProfile() { + ProfileProvider provider = new ProfileProvider(); + ProfilesDao dao = mock(ProfilesDao.class); + Project project = new Project("project").setLanguageKey(Java.KEY); + + MapConfiguration conf = new MapConfiguration(new HashMap()); + conf.addProperty(ProfileProvider.PARAM_PROFILE, "profile1"); + project.setConfiguration(conf); + + when(dao.getProfile(Java.KEY, "profile1")).thenReturn(newProfile()); + + provider.provide(project, dao); + + verify(dao).getProfile(Java.KEY, "profile1"); + verify(dao, never()).getActiveProfile(Java.KEY, "project"); + } + + @Test(expected = RuntimeException.class) + public void shouldFailIfProfileIsNotFound() { + ProfileProvider provider = new ProfileProvider(); + Project project = new Project("project").setLanguageKey(Java.KEY); + ProfilesDao dao = mock(ProfilesDao.class); + + MapConfiguration conf = new MapConfiguration(new HashMap()); + conf.addProperty(ProfileProvider.PARAM_PROFILE, "unknown"); + project.setConfiguration(conf); + + + when(dao.getProfile(Java.KEY, "profile1")).thenReturn(null); + + provider.provide(project, dao); + } + +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/ProjectBuilderTest.java b/sonar-batch/src/test/java/org/sonar/batch/ProjectBuilderTest.java new file mode 100644 index 00000000000..586edaa9300 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/ProjectBuilderTest.java @@ -0,0 +1,210 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.apache.commons.configuration.PropertiesConfiguration; +import org.junit.Before; +import org.junit.Test; +import org.sonar.api.CoreProperties; +import org.sonar.jpa.test.AbstractDbUnitTestCase; +import org.sonar.api.resources.Java; +import org.sonar.api.resources.Project; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class ProjectBuilderTest extends AbstractDbUnitTestCase { + + private ProjectBuilder builder = null; + + @Before + public void before() { + builder = new ProjectBuilder(getSession()); + } + + @Test + public void noExclusionPatterns() { + Project project = new Project("key"); + builder.configure(project, new PropertiesConfiguration()); + + assertThat(project.getExclusionPatterns().length, is(0)); + } + + @Test + public void manyExclusionPatterns() { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, "**/*,foo,*/bar"); + + Project project = new Project("key"); + builder.configure(project, configuration); + + assertThat(project.getExclusionPatterns().length, is(3)); + assertThat(project.getExclusionPatterns()[0], is("**/*")); + assertThat(project.getExclusionPatterns()[1], is("foo")); + assertThat(project.getExclusionPatterns()[2], is("*/bar")); + } + + @Test + public void getLanguageFromConfiguration() { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.setProperty(CoreProperties.PROJECT_LANGUAGE_PROPERTY, "foo"); + + Project project = new Project("key"); + builder.configure(project, configuration); + + assertThat(project.getLanguageKey(), is("foo")); + } + + @Test + public void defaultLanguageIsJava() { + Project project = new Project("key"); + builder.configure(project, new PropertiesConfiguration()); + + assertThat(project.getLanguageKey(), is(Java.KEY)); + } + + @Test + public void analysisIsTodayByDefault() { + Project project = new Project("key"); + builder.configure(project, new PropertiesConfiguration()); + Date today = new Date(); + assertTrue(today.getTime() - project.getAnalysisDate().getTime() < 1000); + } + + @Test + public void analysisDateCouldBeExplicitlySet() { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.setProperty(CoreProperties.PROJECT_DATE_PROPERTY, "2005-01-30"); + Project project = new Project("key"); + builder.configure(project, configuration); + + assertEquals("30012005", new SimpleDateFormat("ddMMyyyy").format(project.getAnalysisDate())); + } + + @Test(expected = RuntimeException.class) + public void failIfAnalyisDateIsNotValid() { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.setProperty(CoreProperties.PROJECT_DATE_PROPERTY, "2005/30/01"); + Project project = new Project("key"); + builder.configure(project, configuration); + + project.getAnalysisDate(); + } + + @Test + public void sonarLightIsDeprecated() { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.setProperty("sonar.light", "true"); + Project project = new Project("key"); + builder.configure(project, configuration); + + assertThat(project.getAnalysisType(), is(Project.AnalysisType.STATIC)); + } + + @Test + public void defaultAnalysisTypeIsDynamic() { + Project project = new Project("key"); + builder.configure(project, new PropertiesConfiguration()); + assertThat(project.getAnalysisType(), is(Project.AnalysisType.DYNAMIC)); + } + + @Test + public void explicitDynamicAnalysis() { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.setProperty(CoreProperties.DYNAMIC_ANALYSIS_PROPERTY, "true"); + Project project = new Project("key"); + builder.configure(project, configuration); + assertThat(project.getAnalysisType(), is(Project.AnalysisType.DYNAMIC)); + } + + @Test + public void explicitStaticAnalysis() { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.setProperty(CoreProperties.DYNAMIC_ANALYSIS_PROPERTY, "false"); + Project project = new Project("key"); + builder.configure(project, configuration); + assertThat(project.getAnalysisType(), is(Project.AnalysisType.STATIC)); + } + + @Test + public void explicitDynamicAnalysisReusingReports() { + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.setProperty(CoreProperties.DYNAMIC_ANALYSIS_PROPERTY, "reuseReports"); + Project project = new Project("key"); + builder.configure(project, configuration); + assertThat(project.getAnalysisType(), is(Project.AnalysisType.REUSE_REPORTS)); + } + + @Test + public void isDynamicAnalysis() { + assertThat(Project.AnalysisType.DYNAMIC.isDynamic(false), is(true)); + assertThat(Project.AnalysisType.DYNAMIC.isDynamic(true), is(true)); + + assertThat(Project.AnalysisType.STATIC.isDynamic(false), is(false)); + assertThat(Project.AnalysisType.STATIC.isDynamic(true), is(false)); + + assertThat(Project.AnalysisType.REUSE_REPORTS.isDynamic(false), is(false)); + assertThat(Project.AnalysisType.REUSE_REPORTS.isDynamic(true), is(true)); + } + + @Test + public void isLatestAnalysis() { + setupData("isLatestAnalysis"); + + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.setProperty(CoreProperties.PROJECT_DATE_PROPERTY, "2010-12-25"); + + Project project = new Project("my:key"); + builder.configure(project, configuration); + + assertThat(project.isLatestAnalysis(), is(true)); + } + + @Test + public void isLatestAnalysisIfNeverAnalysed() { + setupData("isLatestAnalysisIfNeverAnalysed"); + + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.setProperty(CoreProperties.PROJECT_DATE_PROPERTY, "2010-12-25"); + + Project project = new Project("my:key"); + builder.configure(project, configuration); + + assertThat(project.isLatestAnalysis(), is(true)); + } + + @Test + public void isNotLatestAnalysis() { + setupData("isNotLatestAnalysis"); + + PropertiesConfiguration configuration = new PropertiesConfiguration(); + configuration.setProperty(CoreProperties.PROJECT_DATE_PROPERTY, "2005-12-25"); + + Project project = new Project("my:key"); + builder.configure(project, configuration); + + assertThat(project.isLatestAnalysis(), is(false)); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/ProjectConfigurationTest.java b/sonar-batch/src/test/java/org/sonar/batch/ProjectConfigurationTest.java new file mode 100644 index 00000000000..247f0d09c0d --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/ProjectConfigurationTest.java @@ -0,0 +1,117 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.apache.maven.project.MavenProject; +import org.junit.Test; +import org.sonar.jpa.test.AbstractDbUnitTestCase; +import org.sonar.api.resources.Project; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; + +public class ProjectConfigurationTest extends AbstractDbUnitTestCase { + + @Test + public void loadSystemProperties() { + System.setProperty("foo", "bar"); + setupData("global-properties"); + + ProjectConfiguration config = new ProjectConfiguration(getSession(), newProject()); + assertThat(config.getString("foo"), is("bar")); + assertNull(config.getString("unknown")); + } + + @Test + public void loadDatabaseProperties() { + setupData("global-properties"); + ProjectConfiguration config = new ProjectConfiguration(getSession(), newProject()); + assertThat(config.getString("key1"), is("value1")); + assertNull(config.getString("key3")); + } + + @Test + public void loadProjectDatabaseProperties() { + setupData("project-properties"); + ProjectConfiguration config = new ProjectConfiguration(getSession(), newProject()); + assertThat(config.getString("key1"), is("overriden_value1")); + assertThat(config.getString("key2"), is("value2")); + assertThat(config.getString("key3"), is("value3")); + } + + @Test + public void loadModuleDatabaseProperties() { + setupData("modules-properties"); + ProjectConfiguration moduleConfig = new ProjectConfiguration(getSession(), newModule()); + + assertThat(moduleConfig.getString("key1"), is("project_value_1")); + assertThat(moduleConfig.getString("key2"), is("value_2")); + assertThat(moduleConfig.getString("key3"), is("module_value_3")); + assertThat(moduleConfig.getString("key4"), is("module_value_4")); + } + + @Test + public void mavenSettingsLoadedBeforeGlobalSettings() { + setupData("global-properties"); + Project project = newProject(); + project.getPom().getProperties().put("key1", "maven1"); + ProjectConfiguration config = new ProjectConfiguration(getSession(), project); + assertThat(config.getString("key1"), is("maven1")); + } + + @Test + public void projectSettingsLoadedBeforeMavenSettings() { + setupData("project-properties"); + Project project = newProject(); + project.getPom().getProperties().put("key1", "maven1"); + ProjectConfiguration config = new ProjectConfiguration(getSession(), project); + assertThat(config.getString("key1"), is("overriden_value1")); + } + + @Test + public void addPropertyAtRuntime() { + setupData("global-properties"); + ProjectConfiguration config = new ProjectConfiguration(getSession(), newProject()); + + config.getInMemoryConfiguration().setProperty("new-key", "new-value"); + assertThat(config.getString("new-key"), is("new-value")); + } + + @Test + public void overridePropertyAtRuntime() { + setupData("global-properties"); + ProjectConfiguration config = new ProjectConfiguration(getSession(), newProject()); + + assertThat(config.getString("key1"), is("value1")); + config.setProperty("key1", "new1"); + assertThat(config.getString("key1"), is("new1")); + } + + private Project newProject() { + return new Project("mygroup:myproject").setPom(new MavenProject()); + } + + private Project newModule() { + Project module = new Project("mygroup:mymodule").setPom(new MavenProject()); + module.setParent(newProject()); + return module; + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/ProjectTreeTest.java b/sonar-batch/src/test/java/org/sonar/batch/ProjectTreeTest.java new file mode 100644 index 00000000000..8473b959f3d --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/ProjectTreeTest.java @@ -0,0 +1,209 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.commons.io.FileUtils; +import org.apache.maven.model.Model; +import org.apache.maven.model.io.xpp3.MavenXpp3Reader; +import org.apache.maven.project.MavenProject; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import org.junit.Test; +import org.sonar.jpa.test.AbstractDbUnitTestCase; +import org.sonar.api.resources.Project; + +import java.io.File; +import java.io.IOException; +import java.io.StringReader; +import java.net.URISyntaxException; +import java.util.Arrays; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertNull; +import static org.junit.internal.matchers.IsCollectionContaining.hasItem; + + +public class ProjectTreeTest extends AbstractDbUnitTestCase { + + @Test + public void moduleNameShouldEqualArtifactId() throws Exception { + MavenProject parent = loadProject("/org/sonar/batch/ProjectTreeTest/moduleNameShouldEqualArtifactId/pom.xml", true); + MavenProject module1 = loadProject("/org/sonar/batch/ProjectTreeTest/moduleNameShouldEqualArtifactId/module1/pom.xml", false); + MavenProject module2 = loadProject("/org/sonar/batch/ProjectTreeTest/moduleNameShouldEqualArtifactId/module2/pom.xml", false); + + ProjectTree tree = new ProjectTree(newProjectBuilder(), Arrays.asList(parent, module1, module2)); + tree.start(); + + Project root = tree.getRootProject(); + assertThat(root.getModules().size(), is(2)); + assertThat(root.getKey(), is("org.test:parent")); + assertNull(root.getParent()); + assertThat(tree.getProjectByArtifactId("module1").getKey(), is("org.test:module1")); + assertThat(tree.getProjectByArtifactId("module1").getParent(), is(root)); + assertThat(tree.getProjectByArtifactId("module2").getKey(), is("org.test:module2")); + assertThat(tree.getProjectByArtifactId("module2").getParent(), is(root)); + } + + @Test + public void moduleNameDifferentThanArtifactId() throws Exception { + MavenProject parent = loadProject("/org/sonar/batch/ProjectTreeTest/moduleNameDifferentThanArtifactId/pom.xml", true); + MavenProject module1 = loadProject("/org/sonar/batch/ProjectTreeTest/moduleNameDifferentThanArtifactId/path1/pom.xml", false); + MavenProject module2 = loadProject("/org/sonar/batch/ProjectTreeTest/moduleNameDifferentThanArtifactId/path2/pom.xml", false); + + ProjectTree tree = new ProjectTree(newProjectBuilder(), Arrays.asList(parent, module1, module2)); + tree.start(); + + + Project root = tree.getRootProject(); + assertThat(root.getModules().size(), is(2)); + assertThat(root.getKey(), is("org.test:parent")); + assertNull(root.getParent()); + assertThat(tree.getProjectByArtifactId("module1").getKey(), is("org.test:module1")); + assertThat(tree.getProjectByArtifactId("module1").getParent(), is(root)); + assertThat(tree.getProjectByArtifactId("module2").getKey(), is("org.test:module2")); + assertThat(tree.getProjectByArtifactId("module2").getParent(), is(root)); + } + + @Test + public void singleProjectWithoutModules() throws Exception { + MavenProject parent = loadProject("/org/sonar/batch/ProjectTreeTest/singleProjectWithoutModules/pom.xml", true); + + ProjectTree tree = new ProjectTree(newProjectBuilder(), Arrays.asList(parent)); + tree.start(); + + Project root = tree.getRootProject(); + assertThat(root.getModules().size(), is(0)); + assertThat(root.getKey(), is("org.test:parent")); + } + + @Test + public void keyIncludesBranch() throws IOException, XmlPullParserException, URISyntaxException { + MavenProject pom = loadProject("/org/sonar/batch/ProjectTreeTest/keyIncludesBranch/pom.xml", true); + + ProjectTree tree = new ProjectTree(newProjectBuilder(), Arrays.asList(pom)); + tree.start(); + + assertThat(tree.getRootProject().getKey(), is("org.test:project:BRANCH-1.X")); + assertThat(tree.getRootProject().getName(), is("Project BRANCH-1.X")); + } + + + @Test + public void keyIncludesDeprecatedBranch() throws IOException, XmlPullParserException, URISyntaxException { + MavenProject pom = loadProject("/org/sonar/batch/ProjectTreeTest/keyIncludesDeprecatedBranch/pom.xml", true); + + ProjectTree tree = new ProjectTree(newProjectBuilder(), Arrays.asList(pom)); + tree.start(); + + assertThat(tree.getRootProject().getKey(), is("org.test:project:BRANCH-1.X")); + assertThat(tree.getRootProject().getName(), is("Project BRANCH-1.X")); + } + + @Test + public void doNotSkipAnyModules() { + Project foo = newProjectWithArtifactId("root"); + Project bar = newProjectWithArtifactId("sub1"); + Project baz = newProjectWithArtifactId("sub2"); + + ProjectTree tree = new ProjectTree(Arrays.asList(foo, bar, baz)); + tree.applyModuleExclusions(); + + assertThat(tree.getProjects().size(), is(3)); + } + + @Test + public void skipModule() { + Project root = newProjectWithArtifactId("root"); + root.getConfiguration().setProperty("sonar.skippedModules", "sub1"); + Project sub1 = newProjectWithArtifactId("sub1"); + Project sub2 = newProjectWithArtifactId("sub2"); + + ProjectTree tree = new ProjectTree(Arrays.asList(root, sub1, sub2)); + tree.applyModuleExclusions(); + + assertThat(tree.getProjects().size(), is(2)); + assertThat(tree.getProjects(), hasItem(root)); + assertThat(tree.getProjects(), hasItem(sub2)); + } + + @Test + public void skipModules() { + Project root = newProjectWithArtifactId("root"); + root.getConfiguration().setProperty("sonar.skippedModules", "sub1,sub2"); + Project sub1 = newProjectWithArtifactId("sub1"); + Project sub2 = newProjectWithArtifactId("sub2"); + + ProjectTree tree = new ProjectTree(Arrays.asList(root, sub1, sub2)); + tree.applyModuleExclusions(); + + assertThat(tree.getProjects().size(), is(1)); + assertThat(tree.getProjects(), hasItem(root)); + } + + @Test + public void includeModules() { + Project root = newProjectWithArtifactId("root"); + root.getConfiguration().setProperty("sonar.includedModules", "sub1,sub2"); + Project sub1 = newProjectWithArtifactId("sub1"); + Project sub2 = newProjectWithArtifactId("sub2"); + + ProjectTree tree = new ProjectTree(Arrays.asList(root, sub1, sub2)); + tree.applyModuleExclusions(); + + assertThat(tree.getProjects().size(), is(2)); + assertThat(tree.getProjects(), hasItem(sub1)); + assertThat(tree.getProjects(), hasItem(sub2)); + } + + @Test + public void skippedModulesTakePrecedenceOverIncludedModules() { + Project root = newProjectWithArtifactId("root"); + root.getConfiguration().setProperty("sonar.includedModules", "sub1,sub2"); + root.getConfiguration().setProperty("sonar.skippedModules", "sub1"); + Project sub1 = newProjectWithArtifactId("sub1"); + Project sub2 = newProjectWithArtifactId("sub2"); + + ProjectTree tree = new ProjectTree(Arrays.asList(root, sub1, sub2)); + tree.applyModuleExclusions(); + + assertThat(tree.getProjects().size(), is(1)); + assertThat(tree.getProjects(), hasItem(sub2)); + } + + private Project newProjectWithArtifactId(String artifactId) { + MavenProject pom = new MavenProject(); + pom.setArtifactId(artifactId); + return new Project(artifactId).setPom(pom).setConfiguration(new PropertiesConfiguration()); + } + + private MavenProject loadProject(String pomPath, boolean isRoot) throws URISyntaxException, IOException, XmlPullParserException { + File pomFile = new File(getClass().getResource(pomPath).toURI()); + Model model = new MavenXpp3Reader().read(new StringReader(FileUtils.readFileToString(pomFile))); + MavenProject pom = new MavenProject(model); + pom.setFile(pomFile); + pom.setExecutionRoot(isRoot); + return pom; + } + + private ProjectBuilder newProjectBuilder() { + return new ProjectBuilder(getSession()); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/RemoteClassLoaderTest.java b/sonar-batch/src/test/java/org/sonar/batch/RemoteClassLoaderTest.java new file mode 100644 index 00000000000..f79d4535a0e --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/RemoteClassLoaderTest.java @@ -0,0 +1,43 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.junit.Test; + +import java.net.URL; +import java.util.Arrays; + +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.assertNull; + +public class RemoteClassLoaderTest { + + @Test + public void testClassLoader() { + /* foo.jar has just one file /foo/foo.txt */ + assertNull(getClass().getClassLoader().getResource("foo/foo.txt")); + + URL url = getClass().getResource("/org/sonar/batch/RemoteClassLoaderTest/foo.jar"); + RemoteClassLoader classloader = new RemoteClassLoader(Arrays.asList(url), null); + assertNotNull(classloader.getClassLoader()); + assertNotNull(classloader.getClassLoader().getResource("foo/foo.txt")); + + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/ServerMetadataTest.java b/sonar-batch/src/test/java/org/sonar/batch/ServerMetadataTest.java new file mode 100644 index 00000000000..cef7537c63a --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/ServerMetadataTest.java @@ -0,0 +1,61 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.apache.commons.configuration.PropertiesConfiguration; +import org.junit.Test; +import org.sonar.api.CoreProperties; + +import java.text.ParseException; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +public class ServerMetadataTest { + + @Test + public void testLoadProperties() throws ParseException { + PropertiesConfiguration conf = new PropertiesConfiguration(); + conf.setProperty(CoreProperties.SERVER_ID, "123"); + conf.setProperty(CoreProperties.SERVER_VERSION, "2.2"); + conf.setProperty(CoreProperties.SERVER_STARTTIME, "2010-05-18T17:59:00+0000"); + conf.setProperty("sonar.host.url", "http://foo.com"); + + ServerMetadata server = new ServerMetadata(conf); + + assertThat(server.getId(), is("123")); + assertThat(server.getVersion(), is("2.2")); + assertThat(server.getStartedAt().getDate(), is(18)); + assertThat(server.getUrl(), is("http://foo.com")); + } + + /** + * http://jira.codehaus.org/browse/SONAR-1685 + * The maven plugin fails if the property sonar.host.url ends with a slash + */ + @Test + public void urlMustNotEndWithSlash() throws ParseException { + PropertiesConfiguration conf = new PropertiesConfiguration(); + conf.setProperty("sonar.host.url", "http://localhost:80/"); + + ServerMetadata server = new ServerMetadata(conf); + assertThat(server.getUrl(), is("http://localhost:80")); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/ViolationFiltersTest.java b/sonar-batch/src/test/java/org/sonar/batch/ViolationFiltersTest.java new file mode 100644 index 00000000000..53eb38959b2 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/ViolationFiltersTest.java @@ -0,0 +1,68 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch; + +import org.junit.Test; +import org.sonar.api.rules.Violation; +import org.sonar.api.rules.ViolationFilter; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; + +public class ViolationFiltersTest { + + @Test + public void doNotFailIfNoFilters() { + ViolationFilters filters = new ViolationFilters(); + assertThat(filters.isIgnored(new Violation(null)), is(false)); + } + + @Test + public void ignoreViolation() { + ViolationFilters filters = new ViolationFilters(new ViolationFilter[]{ + new FakeFilter(false), + new FakeFilter(true), + new FakeFilter(false), + }); + assertThat(filters.isIgnored(new Violation(null)), is(true)); + } + + @Test + public void doNotIgnoreValidViolations() { + ViolationFilters filters = new ViolationFilters(new ViolationFilter[]{ + new FakeFilter(false), + new FakeFilter(false), + new FakeFilter(false), + }); + assertThat(filters.isIgnored(new Violation(null)), is(false)); + } + + private static class FakeFilter implements ViolationFilter { + private boolean ignore; + + private FakeFilter(boolean ignore) { + this.ignore = ignore; + } + + public boolean isIgnored(Violation violation) { + return ignore; + } + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/indexer/DefaultPersisterTest.java b/sonar-batch/src/test/java/org/sonar/batch/indexer/DefaultPersisterTest.java new file mode 100644 index 00000000000..efeec499d64 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/indexer/DefaultPersisterTest.java @@ -0,0 +1,61 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch.indexer; + +import org.junit.Test; +import org.sonar.jpa.test.AbstractDbUnitTestCase; +import org.sonar.api.database.model.Snapshot; +import org.sonar.api.resources.JavaPackage; +import org.sonar.api.resources.Project; + +public class DefaultPersisterTest extends AbstractDbUnitTestCase { + + @Test + public void createResource() { + setupData("createResource"); + + Bucket bucket = createBucket(new JavaPackage("org.foo")); + + new DefaultPersister(getSession()).persist(bucket); + + checkTables("createResource", "projects", "snapshots"); + } + + private Bucket createBucket(JavaPackage resource) { + Bucket projectBucket = new Bucket(new Project("my:key").setId(5)); + projectBucket.setSnapshot(getSession().getSingleResult(Snapshot.class, "id", 30)); + + Bucket bucket = new Bucket(resource); + bucket.setProject(projectBucket); + bucket.setParent(projectBucket); + return bucket; + } + + @Test + public void updateExistingResource() { + setupData("updateExistingResource"); + + Bucket bucket = createBucket(new JavaPackage("org.foo")); + + new DefaultPersister(getSession()).persist(bucket); + + checkTables("updateExistingResource", "projects", "snapshots"); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/indexer/DefaultSonarIndexTest.java b/sonar-batch/src/test/java/org/sonar/batch/indexer/DefaultSonarIndexTest.java new file mode 100644 index 00000000000..fdbc09cc47c --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/indexer/DefaultSonarIndexTest.java @@ -0,0 +1,56 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch.indexer; + +import org.junit.Test; +import org.sonar.jpa.test.AbstractDbUnitTestCase; +import org.sonar.api.design.Dependency; +import org.sonar.api.resources.JavaFile; +import org.sonar.api.resources.Resource; + +import static junit.framework.Assert.assertTrue; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +public class DefaultSonarIndexTest extends AbstractDbUnitTestCase { + + @Test + public void indexDependencies() { + DefaultSonarIndex index = new DefaultSonarIndex(getSession(), null); + + Resource from = new JavaFile("org.foo.Foo"); + Resource to = new JavaFile("org.bar.Bar"); + Dependency dependency = new Dependency(from, to); + + index.registerDependency(dependency); + + assertThat(index.getDependencies().size(), is(1)); + assertTrue(index.getDependencies().contains(dependency)); + assertThat(index.getEdge(from, to), is(dependency)); + + assertThat(index.getIncomingEdges(to).size(), is(1)); + assertTrue(index.getIncomingEdges(to).contains(dependency)); + assertThat(index.getIncomingEdges(from).isEmpty(), is(true)); + + assertThat(index.getOutgoingEdges(from).size(), is(1)); + assertTrue(index.getOutgoingEdges(from).contains(dependency)); + assertThat(index.getOutgoingEdges(to).isEmpty(), is(true)); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/indexer/LibraryPersisterTest.java b/sonar-batch/src/test/java/org/sonar/batch/indexer/LibraryPersisterTest.java new file mode 100644 index 00000000000..49933e44a7d --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/indexer/LibraryPersisterTest.java @@ -0,0 +1,94 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch.indexer; + +import org.junit.Before; +import org.junit.Test; +import org.sonar.jpa.test.AbstractDbUnitTestCase; +import org.sonar.api.database.model.Snapshot; +import org.sonar.api.resources.Library; +import org.sonar.api.resources.Project; + +import java.text.ParseException; +import java.text.SimpleDateFormat; + +public class LibraryPersisterTest extends AbstractDbUnitTestCase { + + private Bucket<Project> projectBucket; + private LibraryPersister persister; + + @Before + public void before() throws ParseException { + persister = new LibraryPersister(getSession(), new SimpleDateFormat("yyyy-MM-dd HH:mm").parse( "2010-05-18 17:00")); + } + + @Test + public void createLibrary() throws Exception { + setup("createLibrary"); + + Library library = new Library("commons-lang:commons-lang", "1.1") + .setName("Commons Lang"); + + Bucket<Library> bucket = new Bucket<Library>(library).setProject(projectBucket); + persister.persist(bucket); + + check("createLibrary", "projects", "snapshots"); + } + + @Test + public void reuseExistingLibrary() throws Exception { + setup("reuseExistingLibrary"); + + Library library = new Library("commons-lang:commons-lang", "1.1") + .setName("Commons Lang"); + + Bucket<Library> bucket = new Bucket<Library>(library).setProject(projectBucket); + persister.persist(bucket); + + check("reuseExistingLibrary", "projects", "snapshots"); + } + + @Test + public void addNewLibraryVersion() throws Exception { + setup("addNewLibraryVersion"); + + Library library = new Library("commons-lang:commons-lang", "1.2") + .setName("Commons Lang"); + + Bucket<Library> bucket = new Bucket<Library>(library).setProject(projectBucket); + persister.persist(bucket); + + check("addNewLibraryVersion", "projects", "snapshots"); + } + + private void setup(String unitTest) throws Exception { + setupData(unitTest); + + Project project = new Project("my:project"); + project.setId(1); + projectBucket = new Bucket<Project>(project); + projectBucket.setSnapshot(getSession().getSingleResult(Snapshot.class, "id", 1)); + } + + private void check(String unitTest, String... tables) { + getSession().commit(); + checkTables(unitTest, tables); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/indexer/ResourcePersistersTest.java b/sonar-batch/src/test/java/org/sonar/batch/indexer/ResourcePersistersTest.java new file mode 100644 index 00000000000..cb75095aef4 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/indexer/ResourcePersistersTest.java @@ -0,0 +1,67 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch.indexer; + +import org.junit.Test; +import org.sonar.jpa.test.AbstractDbUnitTestCase; +import org.sonar.api.resources.*; + +import static junit.framework.Assert.assertTrue; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +public class ResourcePersistersTest extends AbstractDbUnitTestCase { + + @Test + public void getDefaultPersisterForFilesAndPackages() { + ResourcePersisters persisters = new ResourcePersisters(getSession()); + + + JavaFile file = new JavaFile("org.foo.Bar"); + assertThat(persisters.get(file), is(DefaultPersister.class)); + assertThat(persisters.get(new JavaPackage("org.foo")), is(DefaultPersister.class)); + assertThat(persisters.get(new File("org/foo/Bar.sql")), is(DefaultPersister.class)); + + // always the same instance + assertTrue(persisters.get(file)==persisters.get(file)); + } + + @Test + public void getForProjects() { + ResourcePersisters persisters = new ResourcePersisters(getSession()); + + Project project = new Project("my:project"); + assertThat(persisters.get(project), is(ProjectPersister.class)); + + // always the same instance + assertTrue(persisters.get(project)==persisters.get(project)); + } + + @Test + public void getForLibraries() { + ResourcePersisters persisters = new ResourcePersisters(getSession()); + + Library lib = new Library("commons-lang:commons-lang", "1.0"); + assertThat(persisters.get(lib), is(LibraryPersister.class)); + + // always the same instance + assertTrue(persisters.get(lib)==persisters.get(lib)); + } +} diff --git a/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/avoidConflictWithResourceFromOtherProject-result.xml b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/avoidConflictWithResourceFromOtherProject-result.xml new file mode 100644 index 00000000000..635c73687ec --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/avoidConflictWithResourceFromOtherProject-result.xml @@ -0,0 +1,53 @@ +<dataset> + <metrics id="1" NAME="ncloc" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name="" + enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + <metrics id="2" NAME="coverage" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name="" + enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + + <!-- conflicting resources --> + <projects long_name="[null]" id="1" scope="PRJ" kee="othergroup:artifact" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + <projects long_name="[null]" id="2" scope="DIR" kee="othergroup:artifact:org.sonar" qualifier="PAC" name="org.sonar" + root_id="2" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <projects long_name="[null]" id="10" scope="PRJ" kee="group:artifact" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + <projects long_name="[null]" id="11" scope="DIR" kee="group:artifact:org.sonar" qualifier="PAC" name="org.sonar" + root_id="10" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <!-- the project snapshot --> + <snapshots id="1" created_at="2008-12-25 00:00:00.00" version="1.0" project_id="10" scope="PRJ" qualifier="TRK" + root_project_id="10" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" ISLAST="false" + path="" + depth="0"/> + + <!-- conflicting snapshots --> + <snapshots id="2" created_at="2007-10-02 13:58:00.00" version="2.0" project_id="1" scope="PRJ" qualifier="TRK" + root_project_id="1" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" ISLAST="false" + path="" + depth="0"/> + <snapshots id="3" created_at="2007-10-02 13:58:00.00" version="[null]" project_id="2" scope="DIR" qualifier="PAC" + root_project_id="1" root_snapshot_id="2" parent_snapshot_id="2" STATUS="U" ISLAST="false" path="3." + depth="1"/> + + <!-- the package snapshot --> + <snapshots id="4" created_at="2008-12-25 00:00:00.00" version="[null]" project_id="11" scope="DIR" qualifier="PAC" + root_project_id="10" root_snapshot_id="1" parent_snapshot_id="1" STATUS="U" ISLAST="false" path="1." + depth="1"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" id="1" VALUE="200" METRIC_ID="1" SNAPSHOT_ID="4" RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" id="2" VALUE="80" METRIC_ID="2" SNAPSHOT_ID="4" RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/avoidConflictWithResourceFromOtherProject.xml b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/avoidConflictWithResourceFromOtherProject.xml new file mode 100644 index 00000000000..d47ef4c43a8 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/avoidConflictWithResourceFromOtherProject.xml @@ -0,0 +1,35 @@ +<dataset> + <metrics id="1" NAME="ncloc" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name="" + enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + <metrics id="2" NAME="coverage" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name="" + enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + + <!-- conflicting resources --> + <projects long_name="[null]" id="1" scope="PRJ" kee="othergroup:artifact" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + <projects long_name="[null]" id="2" scope="DIR" kee="othergroup:artifact:org.sonar" qualifier="PAC" name="org.sonar" + root_id="2" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <!-- the project --> + <projects long_name="[null]" id="10" scope="PRJ" kee="group:artifact" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <!-- the project snapshot --> + <snapshots depth="0" id="1" created_at="2008-12-25 00:00:00.00" version="1.0" project_id="10" scope="PRJ" + qualifier="TRK" root_project_id="10" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" + ISLAST="false" path=""/> + + <!-- conflicting snapshots --> + <snapshots depth="0" id="2" created_at="2007-10-02 13:58:00.00" version="2.0" project_id="1" scope="PRJ" + qualifier="TRK" root_project_id="1" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" + ISLAST="false" path=""/> + <snapshots depth="1" id="3" created_at="2007-10-02 13:58:00.00" version="[null]" project_id="2" scope="DIR" + qualifier="PAC" root_project_id="1" root_snapshot_id="2" parent_snapshot_id="2" STATUS="U" + ISLAST="false" + path="3."/> + + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/doNotCacheDatabaseMeasures-result.xml b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/doNotCacheDatabaseMeasures-result.xml new file mode 100644 index 00000000000..31381039d29 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/doNotCacheDatabaseMeasures-result.xml @@ -0,0 +1,20 @@ +<dataset> + <metrics id="1" NAME="ncloc" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name="" + enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + + <projects long_name="[null]" id="10" scope="PRJ" kee="group:artifact" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <snapshots id="1" created_at="2008-12-25 00:00:00.00" version="1.0" project_id="10" scope="PRJ" qualifier="TRK" + root_project_id="[null]" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" ISLAST="false" + path="" + depth="0"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" id="1" VALUE="500" METRIC_ID="1" SNAPSHOT_ID="1" RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/doNotCacheDatabaseMeasures.xml b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/doNotCacheDatabaseMeasures.xml new file mode 100644 index 00000000000..0bd9abf865a --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/doNotCacheDatabaseMeasures.xml @@ -0,0 +1,14 @@ +<dataset> + <metrics id="1" NAME="ncloc" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name="" + enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + + <projects long_name="[null]" id="10" scope="PRJ" kee="group:artifact" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <snapshots id="1" created_at="2008-12-25 00:00:00.00" version="1.0" project_id="10" scope="PRJ" qualifier="TRK" + root_project_id="[null]" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" ISLAST="false" + path="" + depth="0"/> + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/doNotPersistInMemoryMeasures-result.xml b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/doNotPersistInMemoryMeasures-result.xml new file mode 100644 index 00000000000..7b32c5b2c5f --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/doNotPersistInMemoryMeasures-result.xml @@ -0,0 +1,24 @@ +<dataset> + <metrics id="1" NAME="ncloc" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name="" + enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + + <metrics id="2" NAME="coverage" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name="" + enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + + <projects long_name="[null]" id="10" scope="PRJ" kee="group:artifact" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <snapshots id="1" created_at="2008-12-25 00:00:00.00" version="1.0" project_id="10" scope="PRJ" qualifier="TRK" + root_project_id="[null]" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" ISLAST="false" + path="" + depth="0"/> + + + <!-- other measure, just to avoid dbunit to fail --> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" id="1" VALUE="100" METRIC_ID="2" SNAPSHOT_ID="1" RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/doNotPersistInMemoryMeasures.xml b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/doNotPersistInMemoryMeasures.xml new file mode 100644 index 00000000000..7b32c5b2c5f --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/doNotPersistInMemoryMeasures.xml @@ -0,0 +1,24 @@ +<dataset> + <metrics id="1" NAME="ncloc" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name="" + enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + + <metrics id="2" NAME="coverage" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name="" + enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + + <projects long_name="[null]" id="10" scope="PRJ" kee="group:artifact" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <snapshots id="1" created_at="2008-12-25 00:00:00.00" version="1.0" project_id="10" scope="PRJ" qualifier="TRK" + root_project_id="[null]" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" ISLAST="false" + path="" + depth="0"/> + + + <!-- other measure, just to avoid dbunit to fail --> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" id="1" VALUE="100" METRIC_ID="2" SNAPSHOT_ID="1" RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/doNotSaveExcludedResources-result.xml b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/doNotSaveExcludedResources-result.xml new file mode 100644 index 00000000000..0bd9abf865a --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/doNotSaveExcludedResources-result.xml @@ -0,0 +1,14 @@ +<dataset> + <metrics id="1" NAME="ncloc" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name="" + enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + + <projects long_name="[null]" id="10" scope="PRJ" kee="group:artifact" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <snapshots id="1" created_at="2008-12-25 00:00:00.00" version="1.0" project_id="10" scope="PRJ" qualifier="TRK" + root_project_id="[null]" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" ISLAST="false" + path="" + depth="0"/> + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/doNotSaveExcludedResources.xml b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/doNotSaveExcludedResources.xml new file mode 100644 index 00000000000..0bd9abf865a --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/doNotSaveExcludedResources.xml @@ -0,0 +1,14 @@ +<dataset> + <metrics id="1" NAME="ncloc" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name="" + enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + + <projects long_name="[null]" id="10" scope="PRJ" kee="group:artifact" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <snapshots id="1" created_at="2008-12-25 00:00:00.00" version="1.0" project_id="10" scope="PRJ" qualifier="TRK" + root_project_id="[null]" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" ISLAST="false" + path="" + depth="0"/> + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/doNotSaveOptimizedBestValues-result.xml b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/doNotSaveOptimizedBestValues-result.xml new file mode 100644 index 00000000000..524bf2a39af --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/doNotSaveOptimizedBestValues-result.xml @@ -0,0 +1,39 @@ +<dataset> + <metrics id="1" NAME="violations" VAL_TYPE="INT" DESCRIPTION="[null]" DIRECTION="1" domain="[null]" short_name="" + enabled="true" worst_value="[null]" best_value="0" optimized_best_value="true" hidden="false"/> + <metrics id="2" NAME="blocker_violations" VAL_TYPE="INT" DESCRIPTION="[null]" DIRECTION="1" domain="[null]" short_name="" + enabled="true" worst_value="[null]" best_value="0" optimized_best_value="true" hidden="false"/> + + <projects long_name="[null]" id="10" scope="PRJ" kee="group:artifact" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <projects long_name="[null]" id="11" scope="DIR" kee="group:artifact:org.foo" qualifier="PAC" name="org.foo" + root_id="10" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <projects long_name="org.foo.Bar" id="12" scope="FIL" kee="group:artifact:org.foo.Bar" qualifier="CLA" name="Bar" + root_id="10" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <snapshots id="1" created_at="2008-12-25 00:00:00.00" version="1.0" project_id="10" scope="PRJ" qualifier="TRK" + root_project_id="10" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" ISLAST="false" + path="" + depth="0"/> + + <snapshots id="2" created_at="2008-12-25 00:00:00.00" version="[null]" project_id="11" scope="DIR" qualifier="PAC" + root_project_id="10" root_snapshot_id="1" parent_snapshot_id="1" STATUS="U" ISLAST="false" path="1." + depth="1"/> + + <snapshots id="3" created_at="2008-12-25 00:00:00.00" version="[null]" project_id="12" scope="FIL" qualifier="CLA" + root_project_id="10" root_snapshot_id="1" parent_snapshot_id="2" STATUS="U" ISLAST="false" path="1.2." + depth="2"/> + + <!-- violations on file --> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" id="1" VALUE="60" METRIC_ID="1" SNAPSHOT_ID="3" RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/doNotSaveOptimizedBestValues.xml b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/doNotSaveOptimizedBestValues.xml new file mode 100644 index 00000000000..dc2f999d901 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/doNotSaveOptimizedBestValues.xml @@ -0,0 +1,24 @@ +<dataset> + <metrics id="1" NAME="violations" VAL_TYPE="INT" DESCRIPTION="[null]" DIRECTION="1" domain="[null]" short_name="" + enabled="true" worst_value="[null]" best_value="0" optimized_best_value="true" hidden="false" /> + <metrics id="2" NAME="blocker_violations" VAL_TYPE="INT" DESCRIPTION="[null]" DIRECTION="1" domain="[null]" short_name="" + enabled="true" worst_value="[null]" best_value="0" optimized_best_value="true" hidden="false" /> + + <projects long_name="[null]" id="10" scope="PRJ" kee="group:artifact" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <projects long_name="[null]" id="11" scope="DIR" kee="group:artifact:org.foo" qualifier="PAC" name="org.foo" + root_id="10" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <projects long_name="org.foo.Bar" id="12" scope="FIL" kee="group:artifact:org.foo.Bar" qualifier="CLA" name="Bar" + root_id="10" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <snapshots id="1" created_at="2008-12-25 00:00:00.00" version="1.0" project_id="10" scope="PRJ" qualifier="TRK" + root_project_id="10" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" ISLAST="false" + path="" + depth="0"/> + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveDependency-result.xml b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveDependency-result.xml new file mode 100644 index 00000000000..39eca6144cc --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveDependency-result.xml @@ -0,0 +1,36 @@ +<dataset> + <projects long_name="[null]" id="10" scope="PRJ" kee="group:artifact" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <projects long_name="[null]" id="11" scope="DIR" kee="group:artifact:org.sonar.source" qualifier="PAC" + name="org.sonar.source" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <projects long_name="[null]" id="12" scope="DIR" kee="group:artifact:org.sonar.target" qualifier="PAC" + name="org.sonar.target" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + + <snapshots id="1" created_at="2008-12-25 00:00:00.00" version="1.0" project_id="10" scope="PRJ" qualifier="TRK" + root_project_id="10" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" ISLAST="false" + path="" + depth="0"/> + + <snapshots id="2" created_at="2008-12-25 00:00:00.00" version="[null]" project_id="11" scope="DIR" qualifier="PAC" + root_project_id="10" root_snapshot_id="1" parent_snapshot_id="1" STATUS="U" ISLAST="false" + path="1." + depth="1"/> + + <snapshots id="3" created_at="2008-12-25 00:00:00.00" version="[null]" project_id="12" scope="DIR" qualifier="PAC" + root_project_id="10" root_snapshot_id="1" parent_snapshot_id="1" STATUS="U" ISLAST="false" + path="1." + depth="1"/> + + + <dependencies id="1" from_resource_id="11" from_snapshot_id="2" to_resource_id="12" to_snapshot_id="3" + parent_dependency_id="[null]" project_snapshot_id="1" + dep_usage="INHERITS" dep_weight="3" /> +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveDependency.xml b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveDependency.xml new file mode 100644 index 00000000000..a81a295f57e --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveDependency.xml @@ -0,0 +1,22 @@ +<dataset> + <projects long_name="[null]" id="10" scope="PRJ" kee="group:artifact" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <projects long_name="[null]" id="11" scope="DIR" kee="group:artifact:org.sonar.source" qualifier="PAC" + name="org.sonar.source" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <projects long_name="[null]" id="12" scope="DIR" kee="group:artifact:org.sonar.target" qualifier="PAC" + name="org.sonar.target" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + + <snapshots id="1" created_at="2008-12-25 00:00:00.00" version="1.0" project_id="10" scope="PRJ" qualifier="TRK" + root_project_id="10" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" ISLAST="false" + path="" + depth="0"/> + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveMeasureOnExistingResource-result.xml b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveMeasureOnExistingResource-result.xml new file mode 100644 index 00000000000..f7d7623ebde --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveMeasureOnExistingResource-result.xml @@ -0,0 +1,28 @@ +<dataset> + <metrics id="1" NAME="ncloc" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name="" + enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + <metrics id="2" NAME="other" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name="" + enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + + <projects long_name="[null]" id="10" scope="PRJ" kee="group:artifact" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + <projects long_name="[null]" id="11" scope="DIR" kee="group:artifact:org.sonar" qualifier="PAC" name="org.sonar" + root_id="10" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <snapshots id="1" created_at="2008-12-25 00:00:00.00" version="1.0" project_id="10" scope="PRJ" qualifier="TRK" + root_project_id="10" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" ISLAST="false" + path="" + depth="0"/> + <snapshots id="2" created_at="2008-12-25 00:00:00.00" version="[null]" project_id="11" scope="DIR" qualifier="PAC" + root_project_id="10" root_snapshot_id="1" parent_snapshot_id="1" STATUS="U" ISLAST="false" path="1." + depth="1"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" id="1" VALUE="200" METRIC_ID="1" SNAPSHOT_ID="2" RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveMeasureOnExistingResource.xml b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveMeasureOnExistingResource.xml new file mode 100644 index 00000000000..497f2f24ad0 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveMeasureOnExistingResource.xml @@ -0,0 +1,18 @@ +<dataset> + <metrics id="1" NAME="ncloc" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name="" + enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + <metrics id="2" NAME="other" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name="" + enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + + <projects long_name="[null]" id="10" scope="PRJ" kee="group:artifact" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + <projects long_name="[null]" id="11" scope="DIR" kee="group:artifact:org.sonar" qualifier="PAC" name="org.sonar" + root_id="10" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <snapshots id="1" created_at="2008-12-25 00:00:00.00" version="1.0" project_id="10" scope="PRJ" qualifier="TRK" + root_project_id="10" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" ISLAST="false" + path="" + depth="0"/> +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveOptimizedBestValuesIfOptionalFields-result.xml b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveOptimizedBestValuesIfOptionalFields-result.xml new file mode 100644 index 00000000000..c3aed6707b9 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveOptimizedBestValuesIfOptionalFields-result.xml @@ -0,0 +1,37 @@ +<dataset> + <metrics id="1" NAME="violations" VAL_TYPE="INT" DESCRIPTION="[null]" DIRECTION="1" domain="[null]" short_name="" + enabled="true" worst_value="[null]" best_value="0" optimized_best_value="true" hidden="false"/> + + <projects long_name="[null]" id="10" scope="PRJ" kee="group:artifact" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <projects long_name="[null]" id="11" scope="DIR" kee="group:artifact:org.foo" qualifier="PAC" name="org.foo" + root_id="10" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <projects long_name="org.foo.Bar" id="12" scope="FIL" kee="group:artifact:org.foo.Bar" qualifier="CLA" name="Bar" + root_id="10" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <snapshots id="1" created_at="2008-12-25 00:00:00.00" version="1.0" project_id="10" scope="PRJ" qualifier="TRK" + root_project_id="10" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" ISLAST="false" + path="" + depth="0"/> + + <snapshots id="2" created_at="2008-12-25 00:00:00.00" version="[null]" project_id="11" scope="DIR" qualifier="PAC" + root_project_id="10" root_snapshot_id="1" parent_snapshot_id="1" STATUS="U" ISLAST="false" path="1." + depth="1"/> + + <snapshots id="3" created_at="2008-12-25 00:00:00.00" version="[null]" project_id="12" scope="FIL" qualifier="CLA" + root_project_id="10" root_snapshot_id="1" parent_snapshot_id="2" STATUS="U" ISLAST="false" path="1.2." + depth="2"/> + + <!-- violations with default value. It's saved because tendency is set --> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" id="1" VALUE="0" METRIC_ID="1" SNAPSHOT_ID="3" RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" text_value="[null]" tendency="1" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveOptimizedBestValuesIfOptionalFields.xml b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveOptimizedBestValuesIfOptionalFields.xml new file mode 100644 index 00000000000..ee4d8fd9fbb --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveOptimizedBestValuesIfOptionalFields.xml @@ -0,0 +1,22 @@ +<dataset> + <metrics id="1" NAME="violations" VAL_TYPE="INT" DESCRIPTION="[null]" DIRECTION="1" domain="[null]" short_name="" + enabled="true" worst_value="[null]" best_value="0" optimized_best_value="true" hidden="false" /> + + <projects long_name="[null]" id="10" scope="PRJ" kee="group:artifact" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <projects long_name="[null]" id="11" scope="DIR" kee="group:artifact:org.foo" qualifier="PAC" name="org.foo" + root_id="10" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <projects long_name="org.foo.Bar" id="12" scope="FIL" kee="group:artifact:org.foo.Bar" qualifier="CLA" name="Bar" + root_id="10" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <snapshots id="1" created_at="2008-12-25 00:00:00.00" version="1.0" project_id="10" scope="PRJ" qualifier="TRK" + root_project_id="10" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" ISLAST="false" + path="" + depth="0"/> + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveProjectMeasure-result.xml b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveProjectMeasure-result.xml new file mode 100644 index 00000000000..31381039d29 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveProjectMeasure-result.xml @@ -0,0 +1,20 @@ +<dataset> + <metrics id="1" NAME="ncloc" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name="" + enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + + <projects long_name="[null]" id="10" scope="PRJ" kee="group:artifact" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <snapshots id="1" created_at="2008-12-25 00:00:00.00" version="1.0" project_id="10" scope="PRJ" qualifier="TRK" + root_project_id="[null]" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" ISLAST="false" + path="" + depth="0"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" id="1" VALUE="500" METRIC_ID="1" SNAPSHOT_ID="1" RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveProjectMeasure.xml b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveProjectMeasure.xml new file mode 100644 index 00000000000..0bd9abf865a --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveProjectMeasure.xml @@ -0,0 +1,14 @@ +<dataset> + <metrics id="1" NAME="ncloc" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name="" + enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + + <projects long_name="[null]" id="10" scope="PRJ" kee="group:artifact" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <snapshots id="1" created_at="2008-12-25 00:00:00.00" version="1.0" project_id="10" scope="PRJ" qualifier="TRK" + root_project_id="[null]" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" ISLAST="false" + path="" + depth="0"/> + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveResourceTree-result.xml b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveResourceTree-result.xml new file mode 100644 index 00000000000..a8d5bcb9ad6 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveResourceTree-result.xml @@ -0,0 +1,30 @@ +<dataset> + <metrics id="1" NAME="ncloc" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name="" + enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + + <projects long_name="[null]" id="10" scope="PRJ" kee="group:artifact" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <projects long_name="[null]" id="11" scope="DIR" kee="group:artifact:org.foo" qualifier="PAC" name="org.foo" + root_id="10" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <projects long_name="org.foo.Bar" id="12" scope="FIL" kee="group:artifact:org.foo.Bar" qualifier="CLA" name="Bar" + root_id="10" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <snapshots id="1" created_at="2008-12-25 00:00:00.00" version="1.0" project_id="10" scope="PRJ" qualifier="TRK" + root_project_id="10" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" ISLAST="false" + path="" + depth="0"/> + + <snapshots id="2" created_at="2008-12-25 00:00:00.00" version="[null]" project_id="11" scope="DIR" qualifier="PAC" + root_project_id="10" root_snapshot_id="1" parent_snapshot_id="1" STATUS="U" ISLAST="false" path="1." + depth="1"/> + + <snapshots id="3" created_at="2008-12-25 00:00:00.00" version="[null]" project_id="12" scope="FIL" qualifier="CLA" + root_project_id="10" root_snapshot_id="1" parent_snapshot_id="2" STATUS="U" ISLAST="false" path="1.2." + depth="2"/> + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveResourceTree.xml b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveResourceTree.xml new file mode 100644 index 00000000000..2837836be38 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveResourceTree.xml @@ -0,0 +1,14 @@ +<dataset> + <metrics id="1" NAME="ncloc" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name="" + enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + + <projects long_name="[null]" id="10" scope="PRJ" kee="group:artifact" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <snapshots id="1" created_at="2008-12-25 00:00:00.00" version="1.0" project_id="10" scope="PRJ" qualifier="TRK" + root_project_id="10" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" ISLAST="false" + path="" + depth="0"/> + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveResourcesBeforeBuildingDependencies.xml b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveResourcesBeforeBuildingDependencies.xml new file mode 100644 index 00000000000..9a7372deaa8 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveResourcesBeforeBuildingDependencies.xml @@ -0,0 +1,11 @@ +<dataset> + <projects long_name="[null]" id="10" scope="PRJ" kee="group:artifact" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <snapshots id="1" created_at="2008-12-25 00:00:00.00" version="1.0" project_id="10" scope="PRJ" qualifier="TRK" + root_project_id="10" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" ISLAST="false" + path="" + depth="0"/> + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveRuleMeasures-result.xml b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveRuleMeasures-result.xml new file mode 100644 index 00000000000..f0bb10d8e22 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveRuleMeasures-result.xml @@ -0,0 +1,26 @@ +<dataset> + <metrics id="1" NAME="violations" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name="" + enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + + <projects long_name="[null]" id="10" scope="PRJ" kee="group:artifact" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <snapshots id="1" created_at="2008-12-25 00:00:00.00" version="1.0" project_id="10" scope="PRJ" qualifier="TRK" + root_project_id="[null]" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" ISLAST="false" + path="" + depth="0"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" rule_priority="3" + alert_text="[null]" id="1" VALUE="500" METRIC_ID="1" SNAPSHOT_ID="1" RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" id="2" VALUE="200" METRIC_ID="1" SNAPSHOT_ID="1" RULES_CATEGORY_ID="3" + RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveRuleMeasures.xml b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveRuleMeasures.xml new file mode 100644 index 00000000000..f5a8045402c --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/saveRuleMeasures.xml @@ -0,0 +1,14 @@ +<dataset> + <metrics id="1" NAME="violations" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name="" + enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + + <projects long_name="[null]" id="10" scope="PRJ" kee="group:artifact" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <snapshots id="1" created_at="2008-12-25 00:00:00.00" version="1.0" project_id="10" scope="PRJ" qualifier="TRK" + root_project_id="[null]" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" ISLAST="false" + path="" + depth="0"/> + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/updateExistingResourceFields-result.xml b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/updateExistingResourceFields-result.xml new file mode 100644 index 00000000000..8c290640bd5 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/updateExistingResourceFields-result.xml @@ -0,0 +1,22 @@ +<dataset> + <metrics id="1" NAME="ncloc" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name="" + enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + + <projects long_name="[null]" id="10" scope="PRJ" kee="group:artifact" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <projects long_name="[null]" id="11" scope="DIR" qualifier="PAC" kee="group:artifact:org.foo" name="org.foo" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <snapshots id="1" created_at="2008-12-25 00:00:00.00" version="1.0" project_id="10" scope="PRJ" qualifier="TRK" + root_project_id="10" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" ISLAST="false" + path="" + depth="0"/> + + <snapshots id="2" created_at="2008-12-25 00:00:00.00" version="[null]" project_id="11" scope="DIR" qualifier="PAC" + root_project_id="10" root_snapshot_id="1" parent_snapshot_id="1" STATUS="U" ISLAST="false" path="1." + depth="1"/> + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/updateExistingResourceFields.xml b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/updateExistingResourceFields.xml new file mode 100644 index 00000000000..5c90f7296f9 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/DefaultSensorContextTest/updateExistingResourceFields.xml @@ -0,0 +1,18 @@ +<dataset> + <metrics id="1" NAME="ncloc" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name="" + enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + + <projects long_name="[null]" id="10" scope="PRJ" kee="group:artifact" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <projects long_name="[null]" id="11" scope="FOO" qualifier="BAR" kee="group:artifact:org.foo" name="org.foo" + root_id="[null]" + description="[null]" enabled="false" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <snapshots id="1" created_at="2008-12-25 00:00:00.00" version="1.0" project_id="10" scope="PRJ" qualifier="TRK" + root_project_id="10" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" ISLAST="false" + path="" + depth="0"/> + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/DefaultTimeMachineTest/loadMeasuresFromDate.xml b/sonar-batch/src/test/resources/org/sonar/batch/DefaultTimeMachineTest/loadMeasuresFromDate.xml new file mode 100644 index 00000000000..eca84419a8d --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/DefaultTimeMachineTest/loadMeasuresFromDate.xml @@ -0,0 +1,65 @@ +<dataset> + <metrics id="1" NAME="ncloc" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name="" + enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + <metrics id="2" NAME="coverage" VAL_TYPE="INT" DESCRIPTION="[null]" domain="[null]" short_name="" + enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + + <projects long_name="[null]" id="1" scope="PRJ" kee="group:artifact" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + <projects long_name="[null]" id="2" scope="DIR" kee="group:artifact:org.sonar" qualifier="PAC" name="org.sonar" + root_id="2" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + + <!-- Project : 3 snapshots --> + <snapshots id="1" created_at="2008-12-25 00:00:00.00" version="1.0" project_id="1" scope="PRJ" qualifier="TRK" + root_project_id="[null]" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="P" ISLAST="false" + path="" + depth="0"/> + <snapshots id="2" created_at="2009-02-25 13:58:00.00" version="2.0" project_id="1" scope="PRJ" qualifier="TRK" + root_project_id="[null]" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="P" ISLAST="false" + path="" + depth="0"/> + <snapshots id="3" created_at="2009-02-26 15:00:00.00" version="[null]" project_id="1" scope="PRJ" qualifier="TRK" + root_project_id="[null]" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="P" ISLAST="true" + path="" depth="0"/> + + <!-- unprocessed snapshot --> + <snapshots id="4" created_at="2009-02-28 15:00:00.00" version="[null]" project_id="1" scope="PRJ" qualifier="TRK" + root_project_id="[null]" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" ISLAST="false" + path="" depth="0"/> + + <!-- first snapshot measures --> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" id="1" VALUE="200" METRIC_ID="1" SNAPSHOT_ID="1" RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" id="2" VALUE="80" METRIC_ID="2" SNAPSHOT_ID="1" RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <!-- second snapshot measures --> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" id="3" VALUE="230" METRIC_ID="1" SNAPSHOT_ID="2" RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" id="4" VALUE="85" METRIC_ID="2" SNAPSHOT_ID="2" RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + + <!-- third snapshot measures : no coverage --> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" id="5" VALUE="180" METRIC_ID="1" SNAPSHOT_ID="3" RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/FinalizeSnapshotsJobTest/doNotFailIfNoPenultimateLast-result.xml b/sonar-batch/src/test/resources/org/sonar/batch/FinalizeSnapshotsJobTest/doNotFailIfNoPenultimateLast-result.xml new file mode 100644 index 00000000000..a1b5dc5de93 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/FinalizeSnapshotsJobTest/doNotFailIfNoPenultimateLast-result.xml @@ -0,0 +1,22 @@ +<dataset> + <!-- currently processing snapshots --> + <snapshots depth="[null]" id="5" scope="PRJ" qualifier="TRK" created_at="2008-12-04 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true" + path="[null]"/> + + <snapshots depth="[null]" id="6" scope="PRJ" qualifier="TRK" created_at="2008-12-04 13:58:00.00" version="[null]" + project_id="2" + parent_snapshot_id="5" root_project_id="[null]" root_snapshot_id="5" status="P" islast="true" + path="[null]"/> + + <snapshots depth="[null]" id="7" scope="DIR" qualifier="PAC" created_at="2008-12-04 13:58:00.00" version="[null]" + project_id="3" + parent_snapshot_id="6" root_project_id="[null]" root_snapshot_id="5" status="P" islast="true" + path="[null]"/> + + <snapshots depth="[null]" id="8" scope="FIL" qualifier="CLA" created_at="2008-12-04 13:58:00.00" version="[null]" + project_id="4" + parent_snapshot_id="7" root_project_id="[null]" root_snapshot_id="5" status="P" islast="true" + path="[null]"/> +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/FinalizeSnapshotsJobTest/doNotFailIfNoPenultimateLast.xml b/sonar-batch/src/test/resources/org/sonar/batch/FinalizeSnapshotsJobTest/doNotFailIfNoPenultimateLast.xml new file mode 100644 index 00000000000..700793aaeee --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/FinalizeSnapshotsJobTest/doNotFailIfNoPenultimateLast.xml @@ -0,0 +1,23 @@ +<dataset> + + <!-- currently processing snapshots --> + <snapshots depth="[null]" id="5" scope="PRJ" qualifier="TRK" created_at="2008-12-04 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="U" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="6" scope="PRJ" qualifier="TRK" created_at="2008-12-04 13:58:00.00" version="[null]" + project_id="2" + parent_snapshot_id="5" root_project_id="[null]" root_snapshot_id="5" status="U" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="7" scope="DIR" qualifier="PAC" created_at="2008-12-04 13:58:00.00" version="[null]" + project_id="3" + parent_snapshot_id="6" root_project_id="[null]" root_snapshot_id="5" status="U" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="8" scope="FIL" qualifier="CLA" created_at="2008-12-04 13:58:00.00" version="[null]" + project_id="4" + parent_snapshot_id="7" root_project_id="[null]" root_snapshot_id="5" status="U" islast="false" + path="[null]"/> +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/FinalizeSnapshotsJobTest/lastSnapshotIsNotUpdatedWhenAnalyzingPastSnapshot-result.xml b/sonar-batch/src/test/resources/org/sonar/batch/FinalizeSnapshotsJobTest/lastSnapshotIsNotUpdatedWhenAnalyzingPastSnapshot-result.xml new file mode 100644 index 00000000000..1bab0601797 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/FinalizeSnapshotsJobTest/lastSnapshotIsNotUpdatedWhenAnalyzingPastSnapshot-result.xml @@ -0,0 +1,173 @@ +<dataset> + + <!-- last snapshot : is always last, and not purged --> + <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true" + path="[null]"/> + + <snapshots depth="[null]" id="2" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="2" + parent_snapshot_id="1" root_project_id="[null]" root_snapshot_id="1" status="P" islast="true" + path="[null]"/> + + <snapshots depth="[null]" id="3" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="3" + parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="true" + path="[null]"/> + + <snapshots depth="[null]" id="4" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="4" + parent_snapshot_id="3" root_project_id="[null]" root_snapshot_id="1" status="P" islast="true" + path="[null]"/> + + <snapshots depth="[null]" id="5" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="5" + parent_snapshot_id="3" root_project_id="[null]" root_snapshot_id="1" status="P" islast="true" + path="[null]"/> + + + <!-- the snapshot to process : not set as last--> + <snapshots depth="[null]" id="6" scope="PRJ" qualifier="TRK" created_at="2005-10-01 00:00:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="7" scope="PRJ" qualifier="TRK" created_at="2005-10-01 00:00:00.00" version="[null]" + project_id="2" + parent_snapshot_id="6" root_project_id="[null]" root_snapshot_id="6" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="8" scope="DIR" qualifier="PAC" created_at="2005-10-01 00:00:00.00" version="[null]" + project_id="3" + parent_snapshot_id="7" root_project_id="[null]" root_snapshot_id="6" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="9" scope="FIL" qualifier="CLA" created_at="2005-10-01 00:00:00.00" version="[null]" + project_id="4" + parent_snapshot_id="8" root_project_id="[null]" root_snapshot_id="6" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="10" scope="FIL" qualifier="CLA" created_at="2005-10-01 00:00:00.00" version="[null]" + project_id="5" + parent_snapshot_id="9" root_project_id="[null]" root_snapshot_id="6" status="P" islast="false" + path="[null]"/> + + + <SNAPSHOT_SOURCES ID="1" SNAPSHOT_ID="4" DATA="source code of Class1"/> + <SNAPSHOT_SOURCES ID="2" SNAPSHOT_ID="5" DATA="source code of Class2"/> + + <RULE_FAILURES ID="1" SNAPSHOT_ID="4" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg1"/> + <RULE_FAILURES ID="2" SNAPSHOT_ID="4" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg2"/> + <RULE_FAILURES ID="3" SNAPSHOT_ID="4" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg3"/> + <RULE_FAILURES ID="4" SNAPSHOT_ID="4" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg4"/> + + <RULE_FAILURES ID="5" SNAPSHOT_ID="5" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg5"/> + <RULE_FAILURES ID="6" SNAPSHOT_ID="5" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg6"/> + + <!-- measures at project level --> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="1" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="1" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="2" VALUE="20.0" METRIC_ID="2" SNAPSHOT_ID="1" RULES_CATEGORY_ID="1" + RULE_ID="[null]" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="3" VALUE="30.0" METRIC_ID="3" SNAPSHOT_ID="1" RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <!-- measures at module level --> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="4" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="2" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="5" VALUE="20.0" METRIC_ID="2" SNAPSHOT_ID="2" RULES_CATEGORY_ID="1" + RULE_ID="[null]" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="6" VALUE="30.0" METRIC_ID="3" SNAPSHOT_ID="2" RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <!-- measures at package level --> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="7" VALUE="40.0" METRIC_ID="1" SNAPSHOT_ID="3" RULES_CATEGORY_ID="[null]" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="8" VALUE="50.0" METRIC_ID="2" SNAPSHOT_ID="3" RULES_CATEGORY_ID="1" + RULE_ID="[null]" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="9" VALUE="60.0" METRIC_ID="3" SNAPSHOT_ID="3" RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="10" VALUE="60.0" METRIC_ID="3" SNAPSHOT_ID="3" RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <!-- measures at class level --> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="11" VALUE="40.0" METRIC_ID="1" SNAPSHOT_ID="4" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="12" VALUE="50.0" METRIC_ID="2" SNAPSHOT_ID="4" RULES_CATEGORY_ID="1" + RULE_ID="[null]" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="13" VALUE="60.0" METRIC_ID="3" SNAPSHOT_ID="4" RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="14" VALUE="40.0" METRIC_ID="1" SNAPSHOT_ID="5" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="15" VALUE="50.0" METRIC_ID="2" SNAPSHOT_ID="5" RULES_CATEGORY_ID="1" + RULE_ID="[null]" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="16" VALUE="60.0" METRIC_ID="3" SNAPSHOT_ID="5" RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/FinalizeSnapshotsJobTest/lastSnapshotIsNotUpdatedWhenAnalyzingPastSnapshot.xml b/sonar-batch/src/test/resources/org/sonar/batch/FinalizeSnapshotsJobTest/lastSnapshotIsNotUpdatedWhenAnalyzingPastSnapshot.xml new file mode 100644 index 00000000000..c0914d54a78 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/FinalizeSnapshotsJobTest/lastSnapshotIsNotUpdatedWhenAnalyzingPastSnapshot.xml @@ -0,0 +1,174 @@ +<dataset> + + <!-- last snapshot --> + <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true" + path="[null]"/> + + <snapshots depth="[null]" id="2" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="2" + parent_snapshot_id="1" root_project_id="[null]" root_snapshot_id="1" status="P" islast="true" + path="[null]"/> + + <snapshots depth="[null]" id="3" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="3" + parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="true" + path="[null]"/> + + <snapshots depth="[null]" id="4" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="4" + parent_snapshot_id="3" root_project_id="[null]" root_snapshot_id="1" status="P" islast="true" + path="[null]"/> + + <snapshots depth="[null]" id="5" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="5" + parent_snapshot_id="3" root_project_id="[null]" root_snapshot_id="1" status="P" islast="true" + path="[null]"/> + + + <!-- the snapshot to process --> + <snapshots depth="[null]" id="6" scope="PRJ" qualifier="TRK" created_at="2005-10-01 00:00:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="[null]" + islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="7" scope="PRJ" qualifier="TRK" created_at="2005-10-01 00:00:00.00" version="[null]" + project_id="2" + parent_snapshot_id="6" root_project_id="[null]" root_snapshot_id="6" status="[null]" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="8" scope="DIR" qualifier="PAC" created_at="2005-10-01 00:00:00.00" version="[null]" + project_id="3" + parent_snapshot_id="7" root_project_id="[null]" root_snapshot_id="6" status="[null]" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="9" scope="FIL" qualifier="CLA" created_at="2005-10-01 00:00:00.00" version="[null]" + project_id="4" + parent_snapshot_id="8" root_project_id="[null]" root_snapshot_id="6" status="[null]" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="10" scope="FIL" qualifier="CLA" created_at="2005-10-01 00:00:00.00" version="[null]" + project_id="5" + parent_snapshot_id="9" root_project_id="[null]" root_snapshot_id="6" status="[null]" islast="false" + path="[null]"/> + + + <SNAPSHOT_SOURCES ID="1" SNAPSHOT_ID="4" DATA="source code of Class1"/> + <SNAPSHOT_SOURCES ID="2" SNAPSHOT_ID="5" DATA="source code of Class2"/> + + <RULE_FAILURES ID="1" SNAPSHOT_ID="4" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg1"/> + <RULE_FAILURES ID="2" SNAPSHOT_ID="4" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg2"/> + <RULE_FAILURES ID="3" SNAPSHOT_ID="4" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg3"/> + <RULE_FAILURES ID="4" SNAPSHOT_ID="4" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg4"/> + + <RULE_FAILURES ID="5" SNAPSHOT_ID="5" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg5"/> + <RULE_FAILURES ID="6" SNAPSHOT_ID="5" RULE_ID="1" FAILURE_LEVEL="2" MESSAGE="msg6"/> + + <!-- measures at project level --> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="1" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="1" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="2" VALUE="20.0" METRIC_ID="2" SNAPSHOT_ID="1" RULES_CATEGORY_ID="1" + RULE_ID="[null]" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="3" VALUE="30.0" METRIC_ID="3" SNAPSHOT_ID="1" RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <!-- measures at module level --> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="4" VALUE="10.0" METRIC_ID="1" SNAPSHOT_ID="2" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="5" VALUE="20.0" METRIC_ID="2" SNAPSHOT_ID="2" RULES_CATEGORY_ID="1" + RULE_ID="[null]" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="6" VALUE="30.0" METRIC_ID="3" SNAPSHOT_ID="2" RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <!-- measures at package level --> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="7" VALUE="40.0" METRIC_ID="1" SNAPSHOT_ID="3" RULES_CATEGORY_ID="[null]" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="8" VALUE="50.0" METRIC_ID="2" SNAPSHOT_ID="3" RULES_CATEGORY_ID="1" + RULE_ID="[null]" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="9" VALUE="60.0" METRIC_ID="3" SNAPSHOT_ID="3" RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="10" VALUE="60.0" METRIC_ID="3" SNAPSHOT_ID="3" RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <!-- measures at class level --> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="11" VALUE="40.0" METRIC_ID="1" SNAPSHOT_ID="4" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="12" VALUE="50.0" METRIC_ID="2" SNAPSHOT_ID="4" RULES_CATEGORY_ID="1" + RULE_ID="[null]" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="13" VALUE="60.0" METRIC_ID="3" SNAPSHOT_ID="4" RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="14" VALUE="40.0" METRIC_ID="1" SNAPSHOT_ID="5" RULES_CATEGORY_ID="1" + RULE_ID="1" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="15" VALUE="50.0" METRIC_ID="2" SNAPSHOT_ID="5" RULES_CATEGORY_ID="1" + RULE_ID="[null]" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + <project_measures characteristic_id="[null]" url="[null]" diff_value_1="[null]" diff_value_2="[null]" diff_value_3="[null]" + rule_priority="[null]" + alert_text="[null]" ID="16" VALUE="60.0" METRIC_ID="3" SNAPSHOT_ID="5" RULES_CATEGORY_ID="[null]" + RULE_ID="[null]" + text_value="[null]" tendency="[null]" measure_date="[null]" project_id="[null]" + alert_status="[null]" description="[null]"/> + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/FinalizeSnapshotsJobTest/sharedFixture.xml b/sonar-batch/src/test/resources/org/sonar/batch/FinalizeSnapshotsJobTest/sharedFixture.xml new file mode 100644 index 00000000000..00420a0362f --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/FinalizeSnapshotsJobTest/sharedFixture.xml @@ -0,0 +1,38 @@ +<dataset> + <rules_categories id="1" name="category one" description="[null]"/> + <rules id="1" name="foo" rules_category_id="1" plugin_config_key="checker/foo" plugin_rule_key="checkstyle.rule1" + plugin_name="maven-checkstyle-plugin" description="description" cardinality="SINGLE" parent_id="[null]"/> + + <metrics id="1" name="ncloc" val_type="INT" description="[null]" domain="[null]" + short_name="" qualitative="false" user_managed="false" enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + <metrics id="2" name="foo" val_type="INT" description="[null]" domain="[null]" + short_name="" qualitative="false" user_managed="false" enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + <metrics id="3" name="bar" val_type="INT" description="[null]" domain="[null]" + short_name="" qualitative="false" user_managed="false" enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + <metrics id="4" name="baz" val_type="INT" description="[null]" domain="[null]" + short_name="" qualitative="false" user_managed="false" enabled="true" worst_value="[null]" optimized_best_value="[null]" best_value="[null]" direction="0" hidden="false"/> + + <projects long_name="[null]" id="1" scope="PRJ" qualifier="TRK" kee="mygroup:myartifact" name="[null]" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <projects long_name="[null]" id="2" scope="PRJ" qualifier="TRK" kee="mygroup:myartifact2" name="[null]" root_id="1" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <projects long_name="[null]" id="3" scope="DIR" qualifier="PAC" kee="mygroup:myartifact:my.package" name="[null]" + root_id="1" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <projects long_name="[null]" id="4" scope="FIL" qualifier="CLA" kee="mygroup:myartifact:my.package.Class1" + name="[null]" root_id="1" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <projects long_name="[null]" id="5" scope="FIL" qualifier="CLA" kee="mygroup:myartifact:my.package.Class2" + name="[null]" root_id="1" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/FinalizeSnapshotsJobTest/shouldUnflagPenultimateLastSnapshot-result.xml b/sonar-batch/src/test/resources/org/sonar/batch/FinalizeSnapshotsJobTest/shouldUnflagPenultimateLastSnapshot-result.xml new file mode 100644 index 00000000000..815b71743a4 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/FinalizeSnapshotsJobTest/shouldUnflagPenultimateLastSnapshot-result.xml @@ -0,0 +1,55 @@ +<dataset> + + <!-- previous last snapshots --> + <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="2" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="2" + parent_snapshot_id="1" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="3" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="3" + parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="4" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="4" + parent_snapshot_id="3" root_project_id="[null]" root_snapshot_id="1" status="P" islast="false" + path="[null]"/> + + <!-- already purged snapshot --> + <snapshots depth="[null]" id="9" scope="PRJ" qualifier="TRK" created_at="2008-10-02 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="10" scope="PRJ" qualifier="TRK" created_at="2008-10-02 13:58:00.00" version="[null]" + project_id="2" + parent_snapshot_id="9" root_project_id="[null]" root_snapshot_id="9" status="P" islast="false" + path="[null]"/> + + <!-- currently processing snapshots --> + <snapshots depth="[null]" id="11" scope="PRJ" qualifier="TRK" created_at="2008-12-04 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true" + path="[null]"/> + + <snapshots depth="[null]" id="12" scope="PRJ" qualifier="TRK" created_at="2008-12-04 13:58:00.00" version="[null]" + project_id="2" + parent_snapshot_id="11" root_project_id="[null]" root_snapshot_id="11" status="P" islast="true" + path="[null]"/> + + <snapshots depth="[null]" id="13" scope="DIR" qualifier="PAC" created_at="2008-12-04 13:58:00.00" version="[null]" + project_id="3" + parent_snapshot_id="12" root_project_id="[null]" root_snapshot_id="11" status="P" islast="true" + path="[null]"/> + + <snapshots depth="[null]" id="14" scope="FIL" qualifier="CLA" created_at="2008-12-04 13:58:00.00" version="[null]" + project_id="4" + parent_snapshot_id="13" root_project_id="[null]" root_snapshot_id="11" status="P" islast="true" + path="[null]"/> +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/FinalizeSnapshotsJobTest/shouldUnflagPenultimateLastSnapshot.xml b/sonar-batch/src/test/resources/org/sonar/batch/FinalizeSnapshotsJobTest/shouldUnflagPenultimateLastSnapshot.xml new file mode 100644 index 00000000000..7e4130b75d9 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/FinalizeSnapshotsJobTest/shouldUnflagPenultimateLastSnapshot.xml @@ -0,0 +1,57 @@ +<dataset> + + <!-- previous last snapshots --> + <snapshots depth="[null]" id="1" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true" + path="[null]"/> + + <snapshots depth="[null]" id="2" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="2" + parent_snapshot_id="1" root_project_id="[null]" root_snapshot_id="1" status="P" islast="true" + path="[null]"/> + + <snapshots depth="[null]" id="3" scope="DIR" qualifier="PAC" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="3" + parent_snapshot_id="2" root_project_id="[null]" root_snapshot_id="1" status="P" islast="true" + path="[null]"/> + + <snapshots depth="[null]" id="4" scope="FIL" qualifier="CLA" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="4" + parent_snapshot_id="3" root_project_id="[null]" root_snapshot_id="1" status="P" islast="true" + path="[null]"/> + + + <!-- already purged snapshot --> + <snapshots depth="[null]" id="9" scope="PRJ" qualifier="TRK" created_at="2008-10-02 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="10" scope="PRJ" qualifier="TRK" created_at="2008-10-02 13:58:00.00" version="[null]" + project_id="2" + parent_snapshot_id="9" root_project_id="[null]" root_snapshot_id="9" status="P" islast="false" + path="[null]"/> + + + <!-- currently processing snapshots --> + <snapshots depth="[null]" id="11" scope="PRJ" qualifier="TRK" created_at="2008-12-04 13:58:00.00" version="[null]" + project_id="1" + parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="U" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="12" scope="PRJ" qualifier="TRK" created_at="2008-12-04 13:58:00.00" version="[null]" + project_id="2" + parent_snapshot_id="11" root_project_id="[null]" root_snapshot_id="11" status="U" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="13" scope="DIR" qualifier="PAC" created_at="2008-12-04 13:58:00.00" version="[null]" + project_id="3" + parent_snapshot_id="12" root_project_id="[null]" root_snapshot_id="11" status="U" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="14" scope="FIL" qualifier="CLA" created_at="2008-12-04 13:58:00.00" version="[null]" + project_id="4" + parent_snapshot_id="13" root_project_id="[null]" root_snapshot_id="11" status="U" islast="false" + path="[null]"/> +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/MavenPluginsConfiguratorTest/pom.xml b/sonar-batch/src/test/resources/org/sonar/batch/MavenPluginsConfiguratorTest/pom.xml new file mode 100644 index 00000000000..2f95da16602 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/MavenPluginsConfiguratorTest/pom.xml @@ -0,0 +1,19 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>mygroup</groupId> + <artifactId>myartifact</artifactId> + <packaging>jar</packaging> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-checkstyle-plugin</artifactId> + <version>2.2</version> + <configuration> + <outputFileFormat>html</outputFileFormat> + </configuration> + </plugin> + </plugins> + </build> +</project>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/ProjectBuilderTest/isLatestAnalysis.xml b/sonar-batch/src/test/resources/org/sonar/batch/ProjectBuilderTest/isLatestAnalysis.xml new file mode 100644 index 00000000000..0d69b6587a4 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/ProjectBuilderTest/isLatestAnalysis.xml @@ -0,0 +1,15 @@ +<dataset> + + <projects long_name="[null]" id="5" scope="PRJ" qualifier="TRK" kee="my:key" + name="My project" root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <snapshots depth="[null]" id="30" scope="PRJ" qualifier="TRK" created_at="2008-11-01 13:58:00.00" version="[null]" + project_id="5" parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="50" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="5" parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true" + path="[null]"/> +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/ProjectBuilderTest/isLatestAnalysisIfNeverAnalysed.xml b/sonar-batch/src/test/resources/org/sonar/batch/ProjectBuilderTest/isLatestAnalysisIfNeverAnalysed.xml new file mode 100644 index 00000000000..0eecd371324 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/ProjectBuilderTest/isLatestAnalysisIfNeverAnalysed.xml @@ -0,0 +1,12 @@ +<dataset> + + <!-- other project --> + <projects long_name="[null]" id="5" scope="PRJ" qualifier="TRK" kee="other:key" + name="My project" root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <snapshots depth="[null]" id="50" scope="PRJ" qualifier="TRK" created_at="2008-12-02 13:58:00.00" version="[null]" + project_id="5" parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true" + path="[null]"/> +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/ProjectBuilderTest/isNotLatestAnalysis.xml b/sonar-batch/src/test/resources/org/sonar/batch/ProjectBuilderTest/isNotLatestAnalysis.xml new file mode 100644 index 00000000000..98d5825cc37 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/ProjectBuilderTest/isNotLatestAnalysis.xml @@ -0,0 +1,15 @@ +<dataset> + + <projects long_name="[null]" id="5" scope="PRJ" qualifier="TRK" kee="my:key" + name="My project" root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <snapshots depth="[null]" id="30" scope="PRJ" qualifier="TRK" created_at="2010-11-01 13:58:00.00" version="[null]" + project_id="5" parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="false" + path="[null]"/> + + <snapshots depth="[null]" id="50" scope="PRJ" qualifier="TRK" created_at="2010-12-02 13:58:00.00" version="[null]" + project_id="5" parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="P" islast="true" + path="[null]"/> +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/ProjectConfigurationTest/global-properties.xml b/sonar-batch/src/test/resources/org/sonar/batch/ProjectConfigurationTest/global-properties.xml new file mode 100644 index 00000000000..a0f67d7938d --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/ProjectConfigurationTest/global-properties.xml @@ -0,0 +1,18 @@ +<dataset> + + <!-- another project --> + <projects long_name="[null]" id="3333" scope="PRJ" qualifier="TRK" kee="mygroup:anotherproject" name="[null]" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- global properties --> + <properties prop_key="key1" resource_id="[null]" text_value="value1"/> + <properties prop_key="key2" resource_id="[null]" text_value="value2"/> + + <!-- another project properties --> + <properties prop_key="key1" resource_id="3333" text_value="overriden value1"/> + <properties prop_key="key3" resource_id="3333" text_value="value3"/> + + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/ProjectConfigurationTest/modules-properties.xml b/sonar-batch/src/test/resources/org/sonar/batch/ProjectConfigurationTest/modules-properties.xml new file mode 100644 index 00000000000..899e5d2cc02 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/ProjectConfigurationTest/modules-properties.xml @@ -0,0 +1,26 @@ +<dataset> + + <projects long_name="[null]" id="100" scope="PRJ" qualifier="TRK" kee="mygroup:myproject" name="[null]" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <projects long_name="[null]" id="101" scope="PRJ" qualifier="BRC" kee="mygroup:mymodule" name="[null]" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- global properties --> + <properties prop_key="key1" resource_id="[null]" text_value="value_1"/> + <properties prop_key="key2" resource_id="[null]" text_value="value_2"/> + + <!-- project properties --> + <properties prop_key="key1" resource_id="100" text_value="project_value_1"/> + <properties prop_key="key3" resource_id="100" text_value="project_value_3"/> + + <!-- module properties --> + <properties prop_key="key3" resource_id="101" text_value="module_value_3"/> + <properties prop_key="key4" resource_id="101" text_value="module_value_4"/> + + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/ProjectConfigurationTest/project-properties.xml b/sonar-batch/src/test/resources/org/sonar/batch/ProjectConfigurationTest/project-properties.xml new file mode 100644 index 00000000000..b8fa6538b72 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/ProjectConfigurationTest/project-properties.xml @@ -0,0 +1,17 @@ +<dataset> + + <projects long_name="[null]" id="100" scope="PRJ" qualifier="TRK" kee="mygroup:myproject" name="[null]" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- global properties --> + <properties prop_key="key1" resource_id="[null]" text_value="value1"/> + <properties prop_key="key2" resource_id="[null]" text_value="value2"/> + + <!-- specific properties --> + <properties prop_key="key1" resource_id="100" text_value="overriden_value1"/> + <properties prop_key="key3" resource_id="100" text_value="value3"/> + + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/keyIncludesBranch/pom.xml b/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/keyIncludesBranch/pom.xml new file mode 100644 index 00000000000..98ea71c1d09 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/keyIncludesBranch/pom.xml @@ -0,0 +1,12 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>org.test</groupId> + <artifactId>project</artifactId> + <version>0.1-SNAPSHOT</version> + <packaging>pom</packaging> + <name>Project</name> + <properties> + <sonar.branch>BRANCH-1.X</sonar.branch> + </properties> +</project>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/keyIncludesDeprecatedBranch/pom.xml b/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/keyIncludesDeprecatedBranch/pom.xml new file mode 100644 index 00000000000..3fadbf40db1 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/keyIncludesDeprecatedBranch/pom.xml @@ -0,0 +1,12 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>org.test</groupId> + <artifactId>project</artifactId> + <version>0.1-SNAPSHOT</version> + <packaging>pom</packaging> + <name>Project</name> + <properties> + <branch>BRANCH-1.X</branch> + </properties> +</project>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/moduleNameDifferentThanArtifactId/path1/pom.xml b/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/moduleNameDifferentThanArtifactId/path1/pom.xml new file mode 100644 index 00000000000..470f2d1f6e5 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/moduleNameDifferentThanArtifactId/path1/pom.xml @@ -0,0 +1,11 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.test</groupId> + <artifactId>parent</artifactId> + <version>0.1-SNAPSHOT</version> + </parent> + <artifactId>module1</artifactId> + <packaging>jar</packaging> +</project>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/moduleNameDifferentThanArtifactId/path2/pom.xml b/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/moduleNameDifferentThanArtifactId/path2/pom.xml new file mode 100644 index 00000000000..88101678e0f --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/moduleNameDifferentThanArtifactId/path2/pom.xml @@ -0,0 +1,11 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.test</groupId> + <artifactId>parent</artifactId> + <version>0.1-SNAPSHOT</version> + </parent> + <artifactId>module2</artifactId> + <packaging>jar</packaging> +</project>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/moduleNameDifferentThanArtifactId/pom.xml b/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/moduleNameDifferentThanArtifactId/pom.xml new file mode 100644 index 00000000000..afd92c0dbee --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/moduleNameDifferentThanArtifactId/pom.xml @@ -0,0 +1,12 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>org.test</groupId> + <artifactId>parent</artifactId> + <version>0.1-SNAPSHOT</version> + <packaging>pom</packaging> + <modules> + <module>path1</module> + <module>path2</module> + </modules> +</project>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/moduleNameShouldEqualArtifactId/module1/pom.xml b/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/moduleNameShouldEqualArtifactId/module1/pom.xml new file mode 100644 index 00000000000..470f2d1f6e5 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/moduleNameShouldEqualArtifactId/module1/pom.xml @@ -0,0 +1,11 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.test</groupId> + <artifactId>parent</artifactId> + <version>0.1-SNAPSHOT</version> + </parent> + <artifactId>module1</artifactId> + <packaging>jar</packaging> +</project>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/moduleNameShouldEqualArtifactId/module2/pom.xml b/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/moduleNameShouldEqualArtifactId/module2/pom.xml new file mode 100644 index 00000000000..88101678e0f --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/moduleNameShouldEqualArtifactId/module2/pom.xml @@ -0,0 +1,11 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.test</groupId> + <artifactId>parent</artifactId> + <version>0.1-SNAPSHOT</version> + </parent> + <artifactId>module2</artifactId> + <packaging>jar</packaging> +</project>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/moduleNameShouldEqualArtifactId/pom.xml b/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/moduleNameShouldEqualArtifactId/pom.xml new file mode 100644 index 00000000000..cc73a43ec08 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/moduleNameShouldEqualArtifactId/pom.xml @@ -0,0 +1,12 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>org.test</groupId> + <artifactId>parent</artifactId> + <version>0.1-SNAPSHOT</version> + <packaging>pom</packaging> + <modules> + <module>module1</module> + <module>module2</module> + </modules> +</project>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/moduleNameShouldNotEqualArtifactId/path1/pom.xml b/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/moduleNameShouldNotEqualArtifactId/path1/pom.xml new file mode 100644 index 00000000000..470f2d1f6e5 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/moduleNameShouldNotEqualArtifactId/path1/pom.xml @@ -0,0 +1,11 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.test</groupId> + <artifactId>parent</artifactId> + <version>0.1-SNAPSHOT</version> + </parent> + <artifactId>module1</artifactId> + <packaging>jar</packaging> +</project>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/moduleNameShouldNotEqualArtifactId/path2/pom.xml b/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/moduleNameShouldNotEqualArtifactId/path2/pom.xml new file mode 100644 index 00000000000..88101678e0f --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/moduleNameShouldNotEqualArtifactId/path2/pom.xml @@ -0,0 +1,11 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.test</groupId> + <artifactId>parent</artifactId> + <version>0.1-SNAPSHOT</version> + </parent> + <artifactId>module2</artifactId> + <packaging>jar</packaging> +</project>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/moduleNameShouldNotEqualArtifactId/pom.xml b/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/moduleNameShouldNotEqualArtifactId/pom.xml new file mode 100644 index 00000000000..afd92c0dbee --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/moduleNameShouldNotEqualArtifactId/pom.xml @@ -0,0 +1,12 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>org.test</groupId> + <artifactId>parent</artifactId> + <version>0.1-SNAPSHOT</version> + <packaging>pom</packaging> + <modules> + <module>path1</module> + <module>path2</module> + </modules> +</project>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/singleProjectHasNoModules/pom.xml b/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/singleProjectHasNoModules/pom.xml new file mode 100644 index 00000000000..ffd40530c5d --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/singleProjectHasNoModules/pom.xml @@ -0,0 +1,8 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>org.test</groupId> + <artifactId>parent</artifactId> + <version>0.1-SNAPSHOT</version> + <packaging>pom</packaging> +</project>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/singleProjectWithoutModules/pom.xml b/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/singleProjectWithoutModules/pom.xml new file mode 100644 index 00000000000..ffd40530c5d --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/ProjectTreeTest/singleProjectWithoutModules/pom.xml @@ -0,0 +1,8 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>org.test</groupId> + <artifactId>parent</artifactId> + <version>0.1-SNAPSHOT</version> + <packaging>pom</packaging> +</project>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/RemoteClassLoaderTest/foo.jar b/sonar-batch/src/test/resources/org/sonar/batch/RemoteClassLoaderTest/foo.jar Binary files differnew file mode 100644 index 00000000000..c2bde4e5fff --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/RemoteClassLoaderTest/foo.jar diff --git a/sonar-batch/src/test/resources/org/sonar/batch/indexer/DefaultPersisterTest/createResource-result.xml b/sonar-batch/src/test/resources/org/sonar/batch/indexer/DefaultPersisterTest/createResource-result.xml new file mode 100644 index 00000000000..a8540058032 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/indexer/DefaultPersisterTest/createResource-result.xml @@ -0,0 +1,23 @@ +<dataset> + + <projects long_name="My project" id="5" scope="PRJ" qualifier="TRK" kee="my:key" + name="My project" root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]" profile_id="[null]"/> + + <projects long_name="org.foo" id="6" scope="DIR" qualifier="PAC" kee="my:key:org.foo" + name="org.foo" root_id="5" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]" profile_id="[null]"/> + + + + <snapshots depth="0" id="30" scope="PRJ" qualifier="TRK" created_at="2008-11-01 13:58:00.00" version="[null]" + project_id="5" parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="U" islast="false" + path=""/> + + <snapshots depth="1" id="31" scope="DIR" qualifier="PAC" created_at="2008-11-01 13:58:00.00" version="[null]" + project_id="6" parent_snapshot_id="30" root_project_id="5" root_snapshot_id="30" status="U" islast="false" + path="30."/> + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/indexer/DefaultPersisterTest/createResource.xml b/sonar-batch/src/test/resources/org/sonar/batch/indexer/DefaultPersisterTest/createResource.xml new file mode 100644 index 00000000000..a248090db8c --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/indexer/DefaultPersisterTest/createResource.xml @@ -0,0 +1,12 @@ +<dataset> + + <projects long_name="My project" id="5" scope="PRJ" qualifier="TRK" kee="my:key" + name="My project" root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]" profile_id="[null]"/> + + <snapshots depth="0" id="30" scope="PRJ" qualifier="TRK" created_at="2008-11-01 13:58:00.00" version="[null]" + project_id="5" parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="U" islast="false" + path=""/> + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/indexer/DefaultPersisterTest/updateExistingResource-result.xml b/sonar-batch/src/test/resources/org/sonar/batch/indexer/DefaultPersisterTest/updateExistingResource-result.xml new file mode 100644 index 00000000000..a8540058032 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/indexer/DefaultPersisterTest/updateExistingResource-result.xml @@ -0,0 +1,23 @@ +<dataset> + + <projects long_name="My project" id="5" scope="PRJ" qualifier="TRK" kee="my:key" + name="My project" root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]" profile_id="[null]"/> + + <projects long_name="org.foo" id="6" scope="DIR" qualifier="PAC" kee="my:key:org.foo" + name="org.foo" root_id="5" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]" profile_id="[null]"/> + + + + <snapshots depth="0" id="30" scope="PRJ" qualifier="TRK" created_at="2008-11-01 13:58:00.00" version="[null]" + project_id="5" parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="U" islast="false" + path=""/> + + <snapshots depth="1" id="31" scope="DIR" qualifier="PAC" created_at="2008-11-01 13:58:00.00" version="[null]" + project_id="6" parent_snapshot_id="30" root_project_id="5" root_snapshot_id="30" status="U" islast="false" + path="30."/> + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/indexer/DefaultPersisterTest/updateExistingResource.xml b/sonar-batch/src/test/resources/org/sonar/batch/indexer/DefaultPersisterTest/updateExistingResource.xml new file mode 100644 index 00000000000..22b280f539d --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/indexer/DefaultPersisterTest/updateExistingResource.xml @@ -0,0 +1,18 @@ +<dataset> + + <projects long_name="My project" id="5" scope="PRJ" qualifier="TRK" kee="my:key" + name="My project" root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]" profile_id="[null]"/> + + <projects long_name="org.foo" id="6" scope="DIR" qualifier="PAC" kee="my:key:org.foo" + name="org.foo" root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]" profile_id="[null]"/> + + + <snapshots depth="0" id="30" scope="PRJ" qualifier="TRK" created_at="2008-11-01 13:58:00.00" version="[null]" + project_id="5" parent_snapshot_id="[null]" root_project_id="[null]" root_snapshot_id="[null]" status="U" islast="false" + path=""/> + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/indexer/LibraryPersisterTest/addNewLibraryVersion-result.xml b/sonar-batch/src/test/resources/org/sonar/batch/indexer/LibraryPersisterTest/addNewLibraryVersion-result.xml new file mode 100644 index 00000000000..320b08ae0e2 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/indexer/LibraryPersisterTest/addNewLibraryVersion-result.xml @@ -0,0 +1,23 @@ +<dataset> + + <projects long_name="my project" id="1" scope="PRJ" kee="my:project" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <projects long_name="Commons Lang" id="2" scope="PRJ" kee="commons-lang:commons-lang" qualifier="LIB" name="Commons Lang" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="[null]" copy_resource_id="[null]"/> + + <snapshots id="1" created_at="2008-12-25 00:00:00.00" version="1.0" project_id="1" scope="PRJ" qualifier="TRK" + root_project_id="1" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" ISLAST="false" + path="" depth="0"/> + + <snapshots id="2" created_at="2010-05-18 17:00:00.00" version="1.1" project_id="2" scope="PRJ" qualifier="LIB" + root_project_id="2" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="P" ISLAST="false" + path="" depth="0"/> + + <snapshots id="3" created_at="2010-05-18 17:00:00.00" version="1.2" project_id="2" scope="PRJ" qualifier="LIB" + root_project_id="2" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="P" ISLAST="false" + path="" depth="0"/> + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/indexer/LibraryPersisterTest/addNewLibraryVersion.xml b/sonar-batch/src/test/resources/org/sonar/batch/indexer/LibraryPersisterTest/addNewLibraryVersion.xml new file mode 100644 index 00000000000..ba9bcf884f6 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/indexer/LibraryPersisterTest/addNewLibraryVersion.xml @@ -0,0 +1,19 @@ +<dataset> + + <projects long_name="my project" id="1" scope="PRJ" kee="my:project" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <projects long_name="Commons Lang" id="2" scope="PRJ" kee="commons-lang:commons-lang" qualifier="LIB" name="Commons Lang" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="[null]" copy_resource_id="[null]"/> + + <snapshots id="1" created_at="2008-12-25 00:00:00.00" version="1.0" project_id="1" scope="PRJ" qualifier="TRK" + root_project_id="1" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" ISLAST="false" + path="" depth="0"/> + + <snapshots id="2" created_at="2010-05-18 17:00:00.00" version="1.1" project_id="2" scope="PRJ" qualifier="LIB" + root_project_id="2" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="P" ISLAST="false" + path="" depth="0"/> + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/indexer/LibraryPersisterTest/createLibrary-result.xml b/sonar-batch/src/test/resources/org/sonar/batch/indexer/LibraryPersisterTest/createLibrary-result.xml new file mode 100644 index 00000000000..ba9bcf884f6 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/indexer/LibraryPersisterTest/createLibrary-result.xml @@ -0,0 +1,19 @@ +<dataset> + + <projects long_name="my project" id="1" scope="PRJ" kee="my:project" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <projects long_name="Commons Lang" id="2" scope="PRJ" kee="commons-lang:commons-lang" qualifier="LIB" name="Commons Lang" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="[null]" copy_resource_id="[null]"/> + + <snapshots id="1" created_at="2008-12-25 00:00:00.00" version="1.0" project_id="1" scope="PRJ" qualifier="TRK" + root_project_id="1" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" ISLAST="false" + path="" depth="0"/> + + <snapshots id="2" created_at="2010-05-18 17:00:00.00" version="1.1" project_id="2" scope="PRJ" qualifier="LIB" + root_project_id="2" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="P" ISLAST="false" + path="" depth="0"/> + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/indexer/LibraryPersisterTest/createLibrary.xml b/sonar-batch/src/test/resources/org/sonar/batch/indexer/LibraryPersisterTest/createLibrary.xml new file mode 100644 index 00000000000..6f57a77a8cd --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/indexer/LibraryPersisterTest/createLibrary.xml @@ -0,0 +1,11 @@ +<dataset> + + <projects long_name="my project" id="1" scope="PRJ" kee="my:project" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <snapshots id="1" created_at="2008-12-25 00:00:00.00" version="1.0" project_id="1" scope="PRJ" qualifier="TRK" + root_project_id="1" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" ISLAST="false" + path="" depth="0"/> + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/indexer/LibraryPersisterTest/reuseExistingLibrary-result.xml b/sonar-batch/src/test/resources/org/sonar/batch/indexer/LibraryPersisterTest/reuseExistingLibrary-result.xml new file mode 100644 index 00000000000..752dcc20f92 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/indexer/LibraryPersisterTest/reuseExistingLibrary-result.xml @@ -0,0 +1,19 @@ +<dataset> + + <projects long_name="my project" id="1" scope="PRJ" kee="my:project" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <projects long_name="Commons Lang" id="2" scope="PRJ" kee="commons-lang:commons-lang" qualifier="LIB" name="Commons Lang" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="[null]" copy_resource_id="[null]"/> + + <snapshots id="1" created_at="2008-12-25 00:00:00.00" version="1.0" project_id="1" scope="PRJ" qualifier="TRK" + root_project_id="1" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" ISLAST="false" + path="" depth="0"/> + + <snapshots id="2" created_at="[null]" version="1.1" project_id="2" scope="PRJ" qualifier="LIB" + root_project_id="2" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="P" ISLAST="false" + path="" depth="0"/> + +</dataset>
\ No newline at end of file diff --git a/sonar-batch/src/test/resources/org/sonar/batch/indexer/LibraryPersisterTest/reuseExistingLibrary.xml b/sonar-batch/src/test/resources/org/sonar/batch/indexer/LibraryPersisterTest/reuseExistingLibrary.xml new file mode 100644 index 00000000000..752dcc20f92 --- /dev/null +++ b/sonar-batch/src/test/resources/org/sonar/batch/indexer/LibraryPersisterTest/reuseExistingLibrary.xml @@ -0,0 +1,19 @@ +<dataset> + + <projects long_name="my project" id="1" scope="PRJ" kee="my:project" qualifier="TRK" name="my project" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="java" copy_resource_id="[null]"/> + + <projects long_name="Commons Lang" id="2" scope="PRJ" kee="commons-lang:commons-lang" qualifier="LIB" name="Commons Lang" + root_id="[null]" + description="[null]" enabled="true" profile_id="[null]" language="[null]" copy_resource_id="[null]"/> + + <snapshots id="1" created_at="2008-12-25 00:00:00.00" version="1.0" project_id="1" scope="PRJ" qualifier="TRK" + root_project_id="1" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="U" ISLAST="false" + path="" depth="0"/> + + <snapshots id="2" created_at="[null]" version="1.1" project_id="2" scope="PRJ" qualifier="LIB" + root_project_id="2" root_snapshot_id="[null]" parent_snapshot_id="[null]" STATUS="P" ISLAST="false" + path="" depth="0"/> + +</dataset>
\ No newline at end of file |