diff options
author | Julien HENRY <julien.henry@sonarsource.com> | 2015-04-13 09:16:32 +0200 |
---|---|---|
committer | Julien HENRY <julien.henry@sonarsource.com> | 2015-04-14 10:14:30 +0200 |
commit | 91a01dfc9e3d78cbe8b855912202540a66a74cdf (patch) | |
tree | 5865e8bba0934d31b628683605197f327f049ae4 /sonar-batch | |
parent | bd314784e17f2b0573a9e6a25e6a7b8a231c5ed1 (diff) | |
download | sonarqube-91a01dfc9e3d78cbe8b855912202540a66a74cdf.tar.gz sonarqube-91a01dfc9e3d78cbe8b855912202540a66a74cdf.zip |
SONAR-6408 Restore PostJob execution in preview mode
Diffstat (limited to 'sonar-batch')
19 files changed, 555 insertions, 56 deletions
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchExtensionDictionnary.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchExtensionDictionnary.java index 95f333fe93e..0f1eea698ea 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchExtensionDictionnary.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchExtensionDictionnary.java @@ -28,15 +28,19 @@ import org.sonar.api.batch.CheckProject; import org.sonar.api.batch.DependedUpon; import org.sonar.api.batch.DependsUpon; import org.sonar.api.batch.Phase; +import org.sonar.api.batch.postjob.PostJob; +import org.sonar.api.batch.postjob.PostJobContext; import org.sonar.api.batch.sensor.Sensor; import org.sonar.api.batch.sensor.SensorContext; import org.sonar.api.platform.ComponentContainer; import org.sonar.api.resources.Project; import org.sonar.api.utils.AnnotationUtils; import org.sonar.api.utils.dag.DirectAcyclicGraph; -import org.sonar.batch.scan.SensorWrapper; -import org.sonar.batch.sensor.AnalyzerOptimizer; +import org.sonar.batch.postjob.PostJobOptimizer; +import org.sonar.batch.postjob.PostJobWrapper; import org.sonar.batch.sensor.DefaultSensorContext; +import org.sonar.batch.sensor.SensorOptimizer; +import org.sonar.batch.sensor.SensorWrapper; import javax.annotation.Nullable; @@ -55,13 +59,18 @@ import java.util.List; public class BatchExtensionDictionnary { private final ComponentContainer componentContainer; - private final SensorContext context; - private final AnalyzerOptimizer analyzerOptimizer; + private final SensorContext sensorContext; + private final SensorOptimizer sensorOptimizer; + private final PostJobContext postJobContext; + private final PostJobOptimizer postJobOptimizer; - public BatchExtensionDictionnary(ComponentContainer componentContainer, DefaultSensorContext context, AnalyzerOptimizer analyzerOptimizer) { + public BatchExtensionDictionnary(ComponentContainer componentContainer, DefaultSensorContext sensorContext, SensorOptimizer sensorOptimizer, PostJobContext postJobContext, + PostJobOptimizer postJobOptimizer) { this.componentContainer = componentContainer; - this.context = context; - this.analyzerOptimizer = analyzerOptimizer; + this.sensorContext = sensorContext; + this.sensorOptimizer = sensorOptimizer; + this.postJobContext = postJobContext; + this.postJobOptimizer = postJobOptimizer; } public <T> Collection<T> select(Class<T> type, @Nullable Project project, boolean sort, @Nullable ExtensionMatcher matcher) { @@ -90,7 +99,7 @@ public class BatchExtensionDictionnary { List<T> result = Lists.newArrayList(); for (Object extension : getExtensions(type)) { if (org.sonar.api.batch.Sensor.class.equals(type) && extension instanceof Sensor) { - extension = new SensorWrapper((Sensor) extension, context, analyzerOptimizer); + extension = new SensorWrapper((Sensor) extension, sensorContext, sensorOptimizer); } if (shouldKeep(type, extension, project, matcher)) { result.add((T) extension); @@ -99,7 +108,16 @@ public class BatchExtensionDictionnary { if (org.sonar.api.batch.Sensor.class.equals(type)) { // Retrieve new Sensors and wrap then in SensorWrapper for (Object extension : getExtensions(Sensor.class)) { - extension = new SensorWrapper((Sensor) extension, context, analyzerOptimizer); + extension = new SensorWrapper((Sensor) extension, sensorContext, sensorOptimizer); + if (shouldKeep(type, extension, project, matcher)) { + result.add((T) extension); + } + } + } + if (org.sonar.api.batch.PostJob.class.equals(type)) { + // Retrieve new PostJob and wrap then in PostJobWrapper + for (Object extension : getExtensions(PostJob.class)) { + extension = new PostJobWrapper((PostJob) extension, postJobContext, postJobOptimizer); if (shouldKeep(type, extension, project, matcher)) { result.add((T) extension); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/ModuleIssues.java b/sonar-batch/src/main/java/org/sonar/batch/issue/ModuleIssues.java index 64f7e8d2446..f17b42c18db 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/issue/ModuleIssues.java +++ b/sonar-batch/src/main/java/org/sonar/batch/issue/ModuleIssues.java @@ -48,7 +48,7 @@ public class ModuleIssues { private final Project project; private final IssueFilters filters; - public ModuleIssues(ActiveRules activeRules, @Nullable Rules rules, IssueCache cache, @Nullable Project project, IssueFilters filters) { + public ModuleIssues(ActiveRules activeRules, @Nullable Rules rules, IssueCache cache, Project project, IssueFilters filters) { this.activeRules = activeRules; this.rules = rules; this.cache = cache; @@ -56,17 +56,10 @@ public class ModuleIssues { this.filters = filters; } - public ModuleIssues(ActiveRules activeRules, IssueCache cache, @Nullable Project project, IssueFilters filters) { + public ModuleIssues(ActiveRules activeRules, IssueCache cache, Project project, IssueFilters filters) { this(activeRules, null, cache, project, filters); } - /** - * Used by scan2 - */ - public ModuleIssues(ActiveRules activeRules, Rules rules, IssueCache cache, IssueFilters filters) { - this(activeRules, rules, cache, null, filters); - } - public boolean initAndAddViolation(Violation violation) { DefaultIssue issue = newIssue(violation); return initAndAddIssue(issue); diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/DatabaseLessPhaseExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/phases/DatabaseLessPhaseExecutor.java index e116bb80565..9a0d765ca66 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/phases/DatabaseLessPhaseExecutor.java +++ b/sonar-batch/src/main/java/org/sonar/batch/phases/DatabaseLessPhaseExecutor.java @@ -37,6 +37,7 @@ public final class DatabaseLessPhaseExecutor implements PhaseExecutor { private final EventBus eventBus; private final Phases phases; private final InitializersExecutor initializersExecutor; + private final PostJobsExecutor postJobsExecutor; private final SensorsExecutor sensorsExecutor; private final SensorContext sensorContext; private final DefaultIndex index; @@ -49,12 +50,13 @@ public final class DatabaseLessPhaseExecutor implements PhaseExecutor { private final LocalIssueTracking localIssueTracking; private final ReportPublisher reportPublisher; - public DatabaseLessPhaseExecutor(Phases phases, InitializersExecutor initializersExecutor, SensorsExecutor sensorsExecutor, + public DatabaseLessPhaseExecutor(Phases phases, InitializersExecutor initializersExecutor, PostJobsExecutor postJobsExecutor, SensorsExecutor sensorsExecutor, SensorContext sensorContext, DefaultIndex index, EventBus eventBus, ProjectInitializer pi, FileSystemLogger fsLogger, IssuesReports jsonReport, DefaultModuleFileSystem fs, QProfileVerifier profileVerifier, IssueExclusionsLoader issueExclusionsLoader, LocalIssueTracking localIssueTracking, ReportPublisher reportPublisher) { this.phases = phases; this.initializersExecutor = initializersExecutor; + this.postJobsExecutor = postJobsExecutor; this.sensorsExecutor = sensorsExecutor; this.sensorContext = sensorContext; this.index = index; @@ -97,6 +99,9 @@ public final class DatabaseLessPhaseExecutor implements PhaseExecutor { localIssueTracking(); issuesReport(); publishReportJob(); + if (phases.isEnabled(Phases.Phase.POSTJOB)) { + postJobsExecutor.execute(sensorContext); + } } cleanMemory(); diff --git a/sonar-batch/src/main/java/org/sonar/batch/postjob/DefaultPostJobContext.java b/sonar-batch/src/main/java/org/sonar/batch/postjob/DefaultPostJobContext.java new file mode 100644 index 00000000000..56840eb88b4 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/postjob/DefaultPostJobContext.java @@ -0,0 +1,156 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.batch.postjob; + +import com.google.common.base.Function; +import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; +import org.sonar.api.batch.AnalysisMode; +import org.sonar.api.batch.fs.InputPath; +import org.sonar.api.batch.postjob.PostJobContext; +import org.sonar.api.batch.postjob.issue.Issue; +import org.sonar.api.batch.rule.Severity; +import org.sonar.api.config.Settings; +import org.sonar.api.issue.internal.DefaultIssue; +import org.sonar.api.rule.RuleKey; +import org.sonar.batch.index.BatchResource; +import org.sonar.batch.index.ResourceCache; +import org.sonar.batch.issue.IssueCache; + +import javax.annotation.Nullable; + +public class DefaultPostJobContext implements PostJobContext { + + private final Settings settings; + private final AnalysisMode analysisMode; + private final IssueCache cache; + private final ResourceCache resourceCache; + + public DefaultPostJobContext(Settings settings, AnalysisMode analysisMode, IssueCache cache, ResourceCache resourceCache) { + this.settings = settings; + this.analysisMode = analysisMode; + this.cache = cache; + this.resourceCache = resourceCache; + } + + @Override + public Settings settings() { + return settings; + } + + @Override + public AnalysisMode analysisMode() { + return analysisMode; + } + + @Override + public Iterable<Issue> issues() { + return Iterables.transform(Iterables.filter(cache.all(), new ResolvedPredicate(false)), new Function<DefaultIssue, Issue>() { + @Override + public Issue apply(DefaultIssue input) { + return new DefaultIssueWrapper(input); + } + }); + } + + @Override + public Iterable<Issue> resolvedIssues() { + return Iterables.transform(Iterables.filter(cache.all(), new ResolvedPredicate(true)), new Function<DefaultIssue, Issue>() { + @Override + public Issue apply(DefaultIssue input) { + return new DefaultIssueWrapper(input); + } + }); + } + + private class DefaultIssueWrapper implements Issue { + + private final DefaultIssue wrapped; + + public DefaultIssueWrapper(DefaultIssue wrapped) { + this.wrapped = wrapped; + } + + @Override + public String key() { + return wrapped.key(); + } + + @Override + public RuleKey ruleKey() { + return wrapped.ruleKey(); + } + + @Override + public String componentKey() { + return wrapped.componentKey(); + } + + @Override + public InputPath inputPath() { + BatchResource component = resourceCache.get(wrapped.componentKey()); + return component != null ? component.inputPath() : null; + } + + @Override + public Integer line() { + return wrapped.line(); + } + + @Override + public Double effortToFix() { + return wrapped.effortToFix(); + } + + @Override + public String message() { + return wrapped.message(); + } + + @Override + public Severity severity() { + String severity = wrapped.severity(); + return severity != null ? Severity.valueOf(severity) : null; + } + + @Override + public boolean isNew() { + return wrapped.isNew(); + } + + } + + private static class ResolvedPredicate implements Predicate<DefaultIssue> { + private final boolean resolved; + + private ResolvedPredicate(boolean resolved) { + this.resolved = resolved; + } + + @Override + public boolean apply(@Nullable DefaultIssue issue) { + if (issue != null) { + return resolved ? issue.resolution() != null : issue.resolution() == null; + } + return false; + } + } + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/postjob/PostJobOptimizer.java b/sonar-batch/src/main/java/org/sonar/batch/postjob/PostJobOptimizer.java new file mode 100644 index 00000000000..fa4f3ea613a --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/postjob/PostJobOptimizer.java @@ -0,0 +1,67 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.batch.postjob; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.BatchComponent; +import org.sonar.api.batch.AnalysisMode; +import org.sonar.api.batch.postjob.internal.DefaultPostJobDescriptor; +import org.sonar.api.config.Settings; + +public class PostJobOptimizer implements BatchComponent { + + private static final Logger LOG = LoggerFactory.getLogger(PostJobOptimizer.class); + + private final Settings settings; + private final AnalysisMode analysisMode; + + public PostJobOptimizer(Settings settings, AnalysisMode analysisMode) { + this.settings = settings; + this.analysisMode = analysisMode; + } + + /** + * Decide if the given PostJob should be executed. + */ + public boolean shouldExecute(DefaultPostJobDescriptor descriptor) { + if (!settingsCondition(descriptor)) { + LOG.debug("'{}' skipped because one of the required properties is missing", descriptor.name()); + return false; + } + if (descriptor.isDisabledInPreview() && analysisMode.isPreview()) { + LOG.debug("'{}' skipped in preview mode", descriptor.name()); + return false; + } + return true; + } + + private boolean settingsCondition(DefaultPostJobDescriptor descriptor) { + if (!descriptor.properties().isEmpty()) { + for (String propertyKey : descriptor.properties()) { + if (!settings.hasKey(propertyKey)) { + return false; + } + } + } + return true; + } + +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/postjob/PostJobWrapper.java b/sonar-batch/src/main/java/org/sonar/batch/postjob/PostJobWrapper.java new file mode 100644 index 00000000000..45182e69ee5 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/postjob/PostJobWrapper.java @@ -0,0 +1,65 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.batch.postjob; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.batch.CheckProject; +import org.sonar.api.batch.postjob.PostJob; +import org.sonar.api.batch.postjob.PostJobContext; +import org.sonar.api.batch.postjob.internal.DefaultPostJobDescriptor; +import org.sonar.api.resources.Project; + +public class PostJobWrapper implements org.sonar.api.batch.PostJob, CheckProject { + + private static final Logger LOG = LoggerFactory.getLogger(PostJobWrapper.class); + + private PostJob wrappedPostJob; + private PostJobContext adaptor; + private DefaultPostJobDescriptor descriptor; + private PostJobOptimizer optimizer; + + public PostJobWrapper(PostJob newPostJob, PostJobContext adaptor, PostJobOptimizer optimizer) { + this.wrappedPostJob = newPostJob; + this.optimizer = optimizer; + descriptor = new DefaultPostJobDescriptor(); + newPostJob.describe(descriptor); + this.adaptor = adaptor; + } + + public PostJob wrappedPostJob() { + return wrappedPostJob; + } + + @Override + public boolean shouldExecuteOnProject(Project project) { + return optimizer.shouldExecute(descriptor); + } + + @Override + public void executeOn(Project project, org.sonar.api.batch.SensorContext context) { + wrappedPostJob.execute(adaptor); + } + + @Override + public String toString() { + return descriptor.name() + (LOG.isDebugEnabled() ? " (wrapped)" : ""); + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/postjob/package-info.java b/sonar-batch/src/main/java/org/sonar/batch/postjob/package-info.java new file mode 100644 index 00000000000..b4bab61609d --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/postjob/package-info.java @@ -0,0 +1,21 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +@javax.annotation.ParametersAreNonnullByDefault +package org.sonar.batch.postjob; diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java index d9a67454ad0..a05aee3193c 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleScanContainer.java @@ -55,14 +55,16 @@ import org.sonar.batch.issue.tracking.IssueHandlers; import org.sonar.batch.issue.tracking.IssueTrackingDecorator; import org.sonar.batch.language.LanguageDistributionDecorator; import org.sonar.batch.phases.*; +import org.sonar.batch.postjob.DefaultPostJobContext; +import org.sonar.batch.postjob.PostJobOptimizer; import org.sonar.batch.qualitygate.GenerateQualityGateEvents; import org.sonar.batch.qualitygate.QualityGateVerifier; import org.sonar.batch.rule.*; import org.sonar.batch.scan.filesystem.*; import org.sonar.batch.scan.report.IssuesReports; -import org.sonar.batch.sensor.AnalyzerOptimizer; import org.sonar.batch.sensor.DefaultSensorContext; import org.sonar.batch.sensor.DefaultSensorStorage; +import org.sonar.batch.sensor.SensorOptimizer; import org.sonar.batch.sensor.coverage.CoverageExclusions; import org.sonar.batch.source.HighlightableBuilder; import org.sonar.batch.source.SymbolizableBuilder; @@ -134,9 +136,11 @@ public class ModuleScanContainer extends ComponentContainer { ProjectFileSystemAdapter.class, QProfileVerifier.class, - AnalyzerOptimizer.class, + SensorOptimizer.class, + PostJobOptimizer.class, DefaultSensorContext.class, + DefaultPostJobContext.class, DefaultSensorStorage.class, DeprecatedSensorContext.class, BatchExtensionDictionnary.class, diff --git a/sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java b/sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java index 99cdf8bbb70..f73c35c0679 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java +++ b/sonar-batch/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java @@ -29,13 +29,13 @@ import org.sonar.api.batch.fs.TextRange; import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.measure.MetricFinder; import org.sonar.api.batch.rule.ActiveRules; +import org.sonar.api.batch.rule.Severity; import org.sonar.api.batch.sensor.duplication.Duplication; import org.sonar.api.batch.sensor.duplication.internal.DefaultDuplication; import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting; import org.sonar.api.batch.sensor.highlighting.internal.SyntaxHighlightingRule; import org.sonar.api.batch.sensor.internal.SensorStorage; import org.sonar.api.batch.sensor.issue.Issue; -import org.sonar.api.batch.sensor.issue.Issue.Severity; import org.sonar.api.batch.sensor.measure.Measure; import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; import org.sonar.api.config.Settings; diff --git a/sonar-batch/src/main/java/org/sonar/batch/sensor/AnalyzerOptimizer.java b/sonar-batch/src/main/java/org/sonar/batch/sensor/SensorOptimizer.java index f114e4a24e7..dbc4eac19e1 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/sensor/AnalyzerOptimizer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/sensor/SensorOptimizer.java @@ -29,16 +29,16 @@ import org.sonar.api.batch.rule.ActiveRules; import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor; import org.sonar.api.config.Settings; -public class AnalyzerOptimizer implements BatchComponent { +public class SensorOptimizer implements BatchComponent { - private static final Logger LOG = LoggerFactory.getLogger(AnalyzerOptimizer.class); + private static final Logger LOG = LoggerFactory.getLogger(SensorOptimizer.class); private final FileSystem fs; private final ActiveRules activeRules; private final Settings settings; private final AnalysisMode analysisMode; - public AnalyzerOptimizer(FileSystem fs, ActiveRules activeRules, Settings settings, AnalysisMode analysisMode) { + public SensorOptimizer(FileSystem fs, ActiveRules activeRules, Settings settings, AnalysisMode analysisMode) { this.fs = fs; this.activeRules = activeRules; this.settings = settings; @@ -46,7 +46,7 @@ public class AnalyzerOptimizer implements BatchComponent { } /** - * Decide if the given Analyzer should be executed. + * Decide if the given Sensor should be executed. */ public boolean shouldExecute(DefaultSensorDescriptor descriptor) { if (!fsCondition(descriptor)) { diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/SensorWrapper.java b/sonar-batch/src/main/java/org/sonar/batch/sensor/SensorWrapper.java index 8884bef521f..143160e51c0 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/SensorWrapper.java +++ b/sonar-batch/src/main/java/org/sonar/batch/sensor/SensorWrapper.java @@ -17,9 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package org.sonar.batch.scan; - -import org.sonar.batch.sensor.AnalyzerOptimizer; +package org.sonar.batch.sensor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,9 +33,9 @@ public class SensorWrapper implements org.sonar.api.batch.Sensor { private Sensor wrappedSensor; private SensorContext adaptor; private DefaultSensorDescriptor descriptor; - private AnalyzerOptimizer optimizer; + private SensorOptimizer optimizer; - public SensorWrapper(Sensor newSensor, SensorContext adaptor, AnalyzerOptimizer optimizer) { + public SensorWrapper(Sensor newSensor, SensorContext adaptor, SensorOptimizer optimizer) { this.wrappedSensor = newSensor; this.optimizer = optimizer; descriptor = new DefaultSensorDescriptor(); diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchExtensionDictionnaryTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchExtensionDictionnaryTest.java index 046f6664967..14fde3895ef 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchExtensionDictionnaryTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchExtensionDictionnaryTest.java @@ -22,19 +22,13 @@ package org.sonar.batch.bootstrap; import com.google.common.collect.Lists; import org.junit.Test; import org.sonar.api.BatchExtension; -import org.sonar.api.batch.BuildBreaker; -import org.sonar.api.batch.CheckProject; -import org.sonar.api.batch.Decorator; -import org.sonar.api.batch.DependedUpon; -import org.sonar.api.batch.DependsUpon; -import org.sonar.api.batch.Phase; -import org.sonar.api.batch.PostJob; -import org.sonar.api.batch.Sensor; -import org.sonar.api.batch.SensorContext; +import org.sonar.api.batch.*; +import org.sonar.api.batch.postjob.PostJobContext; import org.sonar.api.platform.ComponentContainer; import org.sonar.api.resources.Project; -import org.sonar.batch.sensor.AnalyzerOptimizer; +import org.sonar.batch.postjob.PostJobOptimizer; import org.sonar.batch.sensor.DefaultSensorContext; +import org.sonar.batch.sensor.SensorOptimizer; import java.util.Arrays; import java.util.Collection; @@ -53,7 +47,8 @@ public class BatchExtensionDictionnaryTest { for (BatchExtension extension : extensions) { iocContainer.addSingleton(extension); } - return new BatchExtensionDictionnary(iocContainer, mock(DefaultSensorContext.class), mock(AnalyzerOptimizer.class)); + return new BatchExtensionDictionnary(iocContainer, mock(DefaultSensorContext.class), mock(SensorOptimizer.class), mock(PostJobContext.class), + mock(PostJobOptimizer.class)); } @Test @@ -98,7 +93,8 @@ public class BatchExtensionDictionnaryTest { ComponentContainer child = parent.createChild(); child.addSingleton(c); - BatchExtensionDictionnary dictionnary = new BatchExtensionDictionnary(child, mock(DefaultSensorContext.class), mock(AnalyzerOptimizer.class)); + BatchExtensionDictionnary dictionnary = new BatchExtensionDictionnary(child, mock(DefaultSensorContext.class), mock(SensorOptimizer.class), mock(PostJobContext.class), + mock(PostJobOptimizer.class)); assertThat(dictionnary.select(BatchExtension.class, null, true, null)).containsOnly(a, b, c); } diff --git a/sonar-batch/src/test/java/org/sonar/batch/deprecated/decorator/DecoratorsSelectorTest.java b/sonar-batch/src/test/java/org/sonar/batch/deprecated/decorator/DecoratorsSelectorTest.java index f469d6b52e9..fd9a9ed3727 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/deprecated/decorator/DecoratorsSelectorTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/deprecated/decorator/DecoratorsSelectorTest.java @@ -24,11 +24,7 @@ import org.junit.Test; import org.sonar.api.batch.Decorator; import org.sonar.api.batch.DecoratorContext; import org.sonar.api.batch.DependedUpon; -import org.sonar.api.measures.Formula; -import org.sonar.api.measures.FormulaContext; -import org.sonar.api.measures.FormulaData; -import org.sonar.api.measures.Measure; -import org.sonar.api.measures.Metric; +import org.sonar.api.measures.*; import org.sonar.api.platform.ComponentContainer; import org.sonar.api.resources.Project; import org.sonar.api.resources.Resource; @@ -81,7 +77,7 @@ public class DecoratorsSelectorTest { for (Object extension : extensions) { ioc.addSingleton(extension); } - return new BatchExtensionDictionnary(ioc, null, null); + return new BatchExtensionDictionnary(ioc, null, null, null, null); } class FakeFormula implements Formula { diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java index 22f8a339f13..d97f6ba995d 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java @@ -25,7 +25,7 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import org.sonar.api.batch.sensor.issue.Issue.Severity; +import org.sonar.api.batch.rule.Severity; import org.sonar.batch.mediumtest.BatchMediumTester; import org.sonar.batch.mediumtest.TaskResult; import org.sonar.batch.protocol.input.ActiveRule; diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/PreviewAndReportsMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/PreviewAndReportsMediumTest.java index c8368f37246..ab2157d056d 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/PreviewAndReportsMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/PreviewAndReportsMediumTest.java @@ -163,6 +163,18 @@ public class PreviewAndReportsMediumTest { assertThat(getReportLog()).contains("+13 issues", "+13 major"); } + @Test + public void testPostJob() throws Exception { + File projectDir = new File(PreviewAndReportsMediumTest.class.getResource("/mediumtest/xoo/sample").toURI()); + + tester + .newScanTask(new File(projectDir, "sonar-project.properties")) + .property("sonar.xoo.enablePostJob", "true") + .start(); + + assertThat(logTester.logs()).contains("Resolved issues: 2", "Open issues: 15"); + } + private String getReportLog() { for (String log : logTester.logs()) { if (log.contains(ConsoleReport.HEADER)) { diff --git a/sonar-batch/src/test/java/org/sonar/batch/postjob/DefaultPostJobContextTest.java b/sonar-batch/src/test/java/org/sonar/batch/postjob/DefaultPostJobContextTest.java new file mode 100644 index 00000000000..9ca6dd40771 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/postjob/DefaultPostJobContextTest.java @@ -0,0 +1,87 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.batch.postjob; + +import org.junit.Before; +import org.junit.Test; +import org.sonar.api.batch.AnalysisMode; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.postjob.issue.Issue; +import org.sonar.api.batch.rule.Severity; +import org.sonar.api.config.Settings; +import org.sonar.api.issue.internal.DefaultIssue; +import org.sonar.api.resources.File; +import org.sonar.batch.index.ResourceCache; +import org.sonar.batch.issue.IssueCache; + +import java.util.Arrays; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class DefaultPostJobContextTest { + + private IssueCache issueCache; + private ResourceCache resourceCache; + private AnalysisMode analysisMode; + private DefaultPostJobContext context; + private Settings settings; + + @Before + public void prepare() { + issueCache = mock(IssueCache.class); + resourceCache = new ResourceCache(); + analysisMode = mock(AnalysisMode.class); + settings = new Settings(); + context = new DefaultPostJobContext(settings, analysisMode, issueCache, resourceCache); + } + + @Test + public void test() { + assertThat(context.settings()).isSameAs(settings); + assertThat(context.analysisMode()).isSameAs(analysisMode); + + DefaultIssue defaultIssue = new DefaultIssue(); + defaultIssue.setComponentKey("foo:src/Foo.php"); + defaultIssue.setEffortToFix(2.0); + defaultIssue.setNew(true); + defaultIssue.setKey("xyz"); + defaultIssue.setLine(1); + defaultIssue.setMessage("msg"); + defaultIssue.setSeverity("BLOCKER"); + when(issueCache.all()).thenReturn(Arrays.asList(defaultIssue)); + + Issue issue = context.issues().iterator().next(); + assertThat(issue.componentKey()).isEqualTo("foo:src/Foo.php"); + assertThat(issue.effortToFix()).isEqualTo(2.0); + assertThat(issue.isNew()).isTrue(); + assertThat(issue.key()).isEqualTo("xyz"); + assertThat(issue.line()).isEqualTo(1); + assertThat(issue.message()).isEqualTo("msg"); + assertThat(issue.severity()).isEqualTo(Severity.BLOCKER); + assertThat(issue.inputPath()).isNull(); + + InputFile inputPath = mock(InputFile.class); + resourceCache.add(File.create("src/Foo.php").setEffectiveKey("foo:src/Foo.php"), null).setInputPath(inputPath); + assertThat(issue.inputPath()).isEqualTo(inputPath); + + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/postjob/PostJobOptimizerTest.java b/sonar-batch/src/test/java/org/sonar/batch/postjob/PostJobOptimizerTest.java new file mode 100644 index 00000000000..acd9ea1fdb7 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/postjob/PostJobOptimizerTest.java @@ -0,0 +1,81 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.batch.postjob; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.rules.TemporaryFolder; +import org.sonar.api.batch.AnalysisMode; +import org.sonar.api.batch.postjob.internal.DefaultPostJobDescriptor; +import org.sonar.api.config.Settings; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class PostJobOptimizerTest { + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + private PostJobOptimizer optimizer; + private Settings settings; + private AnalysisMode analysisMode; + + @Before + public void prepare() throws Exception { + settings = new Settings(); + analysisMode = mock(AnalysisMode.class); + optimizer = new PostJobOptimizer(settings, analysisMode); + } + + @Test + public void should_run_analyzer_with_no_metadata() throws Exception { + DefaultPostJobDescriptor descriptor = new DefaultPostJobDescriptor(); + + assertThat(optimizer.shouldExecute(descriptor)).isTrue(); + } + + @Test + public void should_optimize_on_settings() throws Exception { + DefaultPostJobDescriptor descriptor = new DefaultPostJobDescriptor() + .requireProperty("sonar.foo.reportPath"); + assertThat(optimizer.shouldExecute(descriptor)).isFalse(); + + settings.setProperty("sonar.foo.reportPath", "foo"); + assertThat(optimizer.shouldExecute(descriptor)).isTrue(); + } + + @Test + public void should_disabled_in_preview() throws Exception { + DefaultPostJobDescriptor descriptor = new DefaultPostJobDescriptor() + .disabledInPreview(); + assertThat(optimizer.shouldExecute(descriptor)).isTrue(); + + when(analysisMode.isPreview()).thenReturn(true); + + assertThat(optimizer.shouldExecute(descriptor)).isFalse(); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorStorageTest.java b/sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorStorageTest.java index 3114e054718..2ebab61ace3 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorStorageTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/sensor/DefaultSensorStorageTest.java @@ -33,9 +33,9 @@ import org.sonar.api.batch.fs.internal.DefaultInputDir; import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.measure.MetricFinder; import org.sonar.api.batch.rule.ActiveRules; +import org.sonar.api.batch.rule.Severity; import org.sonar.api.batch.rule.internal.ActiveRulesBuilder; import org.sonar.api.batch.sensor.dependency.internal.DefaultDependency; -import org.sonar.api.batch.sensor.issue.Issue.Severity; import org.sonar.api.batch.sensor.issue.internal.DefaultIssue; import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; import org.sonar.api.config.Settings; diff --git a/sonar-batch/src/test/java/org/sonar/batch/sensor/AnalyzerOptimizerTest.java b/sonar-batch/src/test/java/org/sonar/batch/sensor/SensorOptimizerTest.java index 1850fe2b001..12d5e00dc0c 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/sensor/AnalyzerOptimizerTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/sensor/SensorOptimizerTest.java @@ -38,7 +38,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -public class AnalyzerOptimizerTest { +public class SensorOptimizerTest { @Rule public TemporaryFolder temp = new TemporaryFolder(); @@ -47,7 +47,7 @@ public class AnalyzerOptimizerTest { public ExpectedException thrown = ExpectedException.none(); private DefaultFileSystem fs; - private AnalyzerOptimizer optimizer; + private SensorOptimizer optimizer; private Settings settings; private AnalysisMode analysisMode; @@ -56,7 +56,7 @@ public class AnalyzerOptimizerTest { fs = new DefaultFileSystem(temp.newFolder().toPath()); settings = new Settings(); analysisMode = mock(AnalysisMode.class); - optimizer = new AnalyzerOptimizer(fs, new ActiveRulesBuilder().build(), settings, analysisMode); + optimizer = new SensorOptimizer(fs, new ActiveRulesBuilder().build(), settings, analysisMode); } @Test @@ -114,7 +114,7 @@ public class AnalyzerOptimizerTest { .create(RuleKey.of("repo1", "foo")) .activate() .build(); - optimizer = new AnalyzerOptimizer(fs, activeRules, settings, analysisMode); + optimizer = new SensorOptimizer(fs, activeRules, settings, analysisMode); assertThat(optimizer.shouldExecute(descriptor)).isFalse(); @@ -124,7 +124,7 @@ public class AnalyzerOptimizerTest { .create(RuleKey.of("squid", "rule")) .activate() .build(); - optimizer = new AnalyzerOptimizer(fs, activeRules, settings, analysisMode); + optimizer = new SensorOptimizer(fs, activeRules, settings, analysisMode); assertThat(optimizer.shouldExecute(descriptor)).isTrue(); } |