aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-batch
diff options
context:
space:
mode:
authorJulien HENRY <julien.henry@sonarsource.com>2015-02-25 14:04:39 +0100
committerJulien HENRY <julien.henry@sonarsource.com>2015-02-25 14:04:39 +0100
commit908b9d0b5b9c21fabd10d697a5466bcc12d80d83 (patch)
treee95396347367ae8e3e6ea8336aad505f91214ee8 /sonar-batch
parent3414d95ee371418e1e0e45b62f5538a401c33a53 (diff)
downloadsonarqube-908b9d0b5b9c21fabd10d697a5466bcc12d80d83.tar.gz
sonarqube-908b9d0b5b9c21fabd10d697a5466bcc12d80d83.zip
SONAR-5927, SONAR-6012 Rework incremental preview mode to speedup issue retrieval
Diffstat (limited to 'sonar-batch')
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/DefaultAnalysisMode.java17
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalContainer.java25
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/InitialOpenIssuesStack.java6
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTracking.java46
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTrackingDecorator.java10
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTrackingResult.java38
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/LocalIssueTracking.java77
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/PreviousIssueRepository.java87
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/ServerIssue.java (renamed from sonar-batch/src/main/java/org/sonar/batch/issue/tracking/PreviousIssue.java)2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/ServerIssueFromDb.java (renamed from sonar-batch/src/main/java/org/sonar/batch/issue/tracking/PreviousIssueFromDb.java)4
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/ServerIssueFromWs.java (renamed from sonar-batch/src/main/java/org/sonar/batch/issue/tracking/PreviousIssueFromWs.java)18
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/ServerIssueRepository.java122
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/issue/tracking/ServerIssueValueCoder.java47
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java29
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/repository/DefaultServerIssuesLoader.java (renamed from sonar-batch/src/main/java/org/sonar/batch/repository/DefaultPreviousIssuesLoader.java)23
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/repository/ServerIssuesLoader.java (renamed from sonar-batch/src/main/java/org/sonar/batch/repository/PreviousIssuesLoader.java)7
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java4
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan/report/ConsoleReport.java48
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan/report/IssuesReport.java9
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan/report/IssuesReportBuilder.java6
-rw-r--r--sonar-batch/src/main/resources/org/sonar/batch/scan/report/issuesreport.ftl6
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/bootstrap/DefaultAnalysisModeTest.java25
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/issue/tracking/InitialOpenIssuesStackTest.java6
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueTrackingDecoratorTest.java26
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueTrackingTest.java52
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/IncrementalModeMediumTest.java156
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/PreviewAndReportsMediumTest.java107
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/scan/ProjectScanContainerTest.java2
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/scan/report/ConsoleReportTest.java134
29 files changed, 805 insertions, 334 deletions
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/DefaultAnalysisMode.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/DefaultAnalysisMode.java
index 2b5e7bd5577..b13e7b8bab4 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/DefaultAnalysisMode.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/DefaultAnalysisMode.java
@@ -26,6 +26,7 @@ import org.sonar.api.batch.AnalysisMode;
import org.sonar.batch.mediumtest.BatchMediumTester;
import java.text.MessageFormat;
+import java.util.Map;
/**
* @since 4.0
@@ -38,8 +39,8 @@ public class DefaultAnalysisMode implements AnalysisMode {
private boolean incremental;
private boolean mediumTestMode;
- public DefaultAnalysisMode(BootstrapProperties bootstrapProps) {
- init(bootstrapProps);
+ public DefaultAnalysisMode(Map<String, String> props) {
+ init(props);
}
public boolean isDb() {
@@ -60,17 +61,17 @@ public class DefaultAnalysisMode implements AnalysisMode {
return mediumTestMode;
}
- private void init(BootstrapProperties bootstrapProps) {
- if (bootstrapProps.properties().containsKey(CoreProperties.DRY_RUN)) {
+ private void init(Map<String, String> props) {
+ if (props.containsKey(CoreProperties.DRY_RUN)) {
LOG.warn(MessageFormat.format("Property {0} is deprecated. Please use {1} instead.", CoreProperties.DRY_RUN, CoreProperties.ANALYSIS_MODE));
- preview = "true".equals(bootstrapProps.property(CoreProperties.DRY_RUN));
+ preview = "true".equals(props.get(CoreProperties.DRY_RUN));
incremental = false;
} else {
- String mode = bootstrapProps.property(CoreProperties.ANALYSIS_MODE);
+ String mode = props.get(CoreProperties.ANALYSIS_MODE);
preview = CoreProperties.ANALYSIS_MODE_PREVIEW.equals(mode);
incremental = CoreProperties.ANALYSIS_MODE_INCREMENTAL.equals(mode);
}
- mediumTestMode = "true".equals(bootstrapProps.property(BatchMediumTester.MEDIUM_TEST_ENABLED));
+ mediumTestMode = "true".equals(props.get(BatchMediumTester.MEDIUM_TEST_ENABLED));
if (incremental) {
LOG.info("Incremental mode");
} else if (preview) {
@@ -81,7 +82,7 @@ public class DefaultAnalysisMode implements AnalysisMode {
}
// To stay compatible with plugins that use the old property to check mode
if (incremental || preview) {
- bootstrapProps.properties().put(CoreProperties.DRY_RUN, "true");
+ props.put(CoreProperties.DRY_RUN, "true");
}
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalContainer.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalContainer.java
index 80525697653..7cf0bd61ef8 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalContainer.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/GlobalContainer.java
@@ -19,14 +19,6 @@
*/
package org.sonar.batch.bootstrap;
-import org.sonar.batch.components.PastSnapshotFinder;
-
-import org.sonar.batch.deprecated.components.PastSnapshotFinderByDate;
-import org.sonar.batch.deprecated.components.PastSnapshotFinderByDays;
-import org.sonar.batch.deprecated.components.PastSnapshotFinderByPreviousAnalysis;
-import org.sonar.batch.deprecated.components.PastSnapshotFinderByPreviousVersion;
-import org.sonar.batch.deprecated.components.PastSnapshotFinderByVersion;
-import org.sonar.batch.repository.user.UserRepository;
import org.sonar.api.Plugin;
import org.sonar.api.config.EmailSettings;
import org.sonar.api.platform.ComponentContainer;
@@ -36,14 +28,21 @@ import org.sonar.api.utils.HttpDownloader;
import org.sonar.api.utils.System2;
import org.sonar.api.utils.UriReader;
import org.sonar.api.utils.internal.TempFolderCleaner;
+import org.sonar.batch.components.PastSnapshotFinder;
+import org.sonar.batch.deprecated.components.PastSnapshotFinderByDate;
+import org.sonar.batch.deprecated.components.PastSnapshotFinderByDays;
+import org.sonar.batch.deprecated.components.PastSnapshotFinderByPreviousAnalysis;
+import org.sonar.batch.deprecated.components.PastSnapshotFinderByPreviousVersion;
+import org.sonar.batch.deprecated.components.PastSnapshotFinderByVersion;
import org.sonar.batch.platform.DefaultServer;
import org.sonar.batch.repository.DefaultGlobalRepositoriesLoader;
-import org.sonar.batch.repository.DefaultPreviousIssuesLoader;
import org.sonar.batch.repository.DefaultProjectRepositoriesLoader;
+import org.sonar.batch.repository.DefaultServerIssuesLoader;
import org.sonar.batch.repository.GlobalRepositoriesLoader;
import org.sonar.batch.repository.GlobalRepositoriesProvider;
-import org.sonar.batch.repository.PreviousIssuesLoader;
import org.sonar.batch.repository.ProjectRepositoriesLoader;
+import org.sonar.batch.repository.ServerIssuesLoader;
+import org.sonar.batch.repository.user.UserRepository;
import org.sonar.core.cluster.NullQueue;
import org.sonar.core.config.Logback;
import org.sonar.core.i18n.DefaultI18n;
@@ -81,7 +80,7 @@ public class GlobalContainer extends ComponentContainer {
@Override
protected void doBeforeStart() {
BootstrapProperties bootstrapProps = new BootstrapProperties(bootstrapProperties);
- DefaultAnalysisMode analysisMode = new DefaultAnalysisMode(bootstrapProps);
+ DefaultAnalysisMode analysisMode = new DefaultAnalysisMode(bootstrapProps.properties());
add(bootstrapProps, analysisMode);
addBootstrapComponents();
if (analysisMode.isDb()) {
@@ -117,8 +116,8 @@ public class GlobalContainer extends ComponentContainer {
if (getComponentByType(ProjectRepositoriesLoader.class) == null) {
add(DefaultProjectRepositoriesLoader.class);
}
- if (getComponentByType(PreviousIssuesLoader.class) == null) {
- add(DefaultPreviousIssuesLoader.class);
+ if (getComponentByType(ServerIssuesLoader.class) == null) {
+ add(DefaultServerIssuesLoader.class);
}
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/InitialOpenIssuesStack.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/InitialOpenIssuesStack.java
index acc9ebf21b8..6d246b74606 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/InitialOpenIssuesStack.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/InitialOpenIssuesStack.java
@@ -49,11 +49,11 @@ public class InitialOpenIssuesStack implements BatchExtension {
return this;
}
- public List<PreviousIssue> selectAndRemoveIssues(String componentKey) {
+ public List<ServerIssue> selectAndRemoveIssues(String componentKey) {
Iterable<IssueDto> issues = issuesCache.values(componentKey);
- List<PreviousIssue> result = newArrayList();
+ List<ServerIssue> result = newArrayList();
for (IssueDto issue : issues) {
- result.add(new PreviousIssueFromDb(issue));
+ result.add(new ServerIssueFromDb(issue));
}
issuesCache.clear(componentKey);
return result;
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTracking.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTracking.java
index 2c1c49afa97..54c7970bc34 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTracking.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTracking.java
@@ -44,7 +44,7 @@ public class IssueTracking implements BatchComponent {
/**
* @param sourceHashHolder Null when working on resource that is not a file (directory/project)
*/
- public IssueTrackingResult track(@Nullable SourceHashHolder sourceHashHolder, Collection<PreviousIssue> previousIssues, Collection<DefaultIssue> newIssues) {
+ public IssueTrackingResult track(@Nullable SourceHashHolder sourceHashHolder, Collection<ServerIssue> previousIssues, Collection<DefaultIssue> newIssues) {
IssueTrackingResult result = new IssueTrackingResult();
if (sourceHashHolder != null) {
@@ -69,7 +69,7 @@ public class IssueTracking implements BatchComponent {
}
@VisibleForTesting
- void mapIssues(Collection<DefaultIssue> newIssues, @Nullable Collection<PreviousIssue> previousIssues, @Nullable SourceHashHolder sourceHashHolder, IssueTrackingResult result) {
+ void mapIssues(Collection<DefaultIssue> newIssues, @Nullable Collection<ServerIssue> previousIssues, @Nullable SourceHashHolder sourceHashHolder, IssueTrackingResult result) {
boolean hasLastScan = false;
if (previousIssues != null) {
@@ -89,8 +89,8 @@ public class IssueTracking implements BatchComponent {
}
}
- private void mapLastIssues(Collection<DefaultIssue> newIssues, Collection<PreviousIssue> previousIssues, IssueTrackingResult result) {
- for (PreviousIssue lastIssue : previousIssues) {
+ private void mapLastIssues(Collection<DefaultIssue> newIssues, Collection<ServerIssue> previousIssues, IssueTrackingResult result) {
+ for (ServerIssue lastIssue : previousIssues) {
result.addUnmatched(lastIssue);
}
@@ -118,7 +118,7 @@ public class IssueTracking implements BatchComponent {
RollingFileHashes b = RollingFileHashes.create(hashedSource, 5);
Multimap<Integer, DefaultIssue> newIssuesByLines = newIssuesByLines(newIssues, rec, result);
- Multimap<Integer, PreviousIssue> lastIssuesByLines = lastIssuesByLines(result.unmatched(), rec);
+ Multimap<Integer, ServerIssue> lastIssuesByLines = lastIssuesByLines(result.unmatched(), rec);
Map<Integer, HashOccurrence> map = Maps.newHashMap();
@@ -204,10 +204,10 @@ public class IssueTracking implements BatchComponent {
}
}
- private void map(Collection<DefaultIssue> newIssues, Collection<PreviousIssue> previousIssues, IssueTrackingResult result) {
+ private void map(Collection<DefaultIssue> newIssues, Collection<ServerIssue> previousIssues, IssueTrackingResult result) {
for (DefaultIssue newIssue : newIssues) {
if (isNotAlreadyMapped(newIssue, result)) {
- for (PreviousIssue previousIssue : previousIssues) {
+ for (ServerIssue previousIssue : previousIssues) {
if (isNotAlreadyMapped(previousIssue, result) && Objects.equal(newIssue.ruleKey(), previousIssue.ruleKey())) {
mapIssue(newIssue, previousIssue, result);
break;
@@ -227,9 +227,9 @@ public class IssueTracking implements BatchComponent {
return newIssuesByLines;
}
- private Multimap<Integer, PreviousIssue> lastIssuesByLines(Collection<PreviousIssue> previousIssues, IssueTrackingBlocksRecognizer rec) {
- Multimap<Integer, PreviousIssue> previousIssuesByLines = LinkedHashMultimap.create();
- for (PreviousIssue previousIssue : previousIssues) {
+ private Multimap<Integer, ServerIssue> lastIssuesByLines(Collection<ServerIssue> previousIssues, IssueTrackingBlocksRecognizer rec) {
+ Multimap<Integer, ServerIssue> previousIssuesByLines = LinkedHashMultimap.create();
+ for (ServerIssue previousIssue : previousIssues) {
if (rec.isValidLineInReference(previousIssue.line())) {
previousIssuesByLines.put(previousIssue.line(), previousIssue);
}
@@ -237,8 +237,8 @@ public class IssueTracking implements BatchComponent {
return previousIssuesByLines;
}
- private PreviousIssue findLastIssueWithSameChecksum(DefaultIssue newIssue, Collection<PreviousIssue> previousIssues) {
- for (PreviousIssue previousIssue : previousIssues) {
+ private ServerIssue findLastIssueWithSameChecksum(DefaultIssue newIssue, Collection<ServerIssue> previousIssues) {
+ for (ServerIssue previousIssue : previousIssues) {
if (isSameChecksum(newIssue, previousIssue)) {
return previousIssue;
}
@@ -246,8 +246,8 @@ public class IssueTracking implements BatchComponent {
return null;
}
- private PreviousIssue findLastIssueWithSameLineAndMessage(DefaultIssue newIssue, Collection<PreviousIssue> previousIssues) {
- for (PreviousIssue previousIssue : previousIssues) {
+ private ServerIssue findLastIssueWithSameLineAndMessage(DefaultIssue newIssue, Collection<ServerIssue> previousIssues) {
+ for (ServerIssue previousIssue : previousIssues) {
if (isSameLine(newIssue, previousIssue) && isSameMessage(newIssue, previousIssue)) {
return previousIssue;
}
@@ -255,8 +255,8 @@ public class IssueTracking implements BatchComponent {
return null;
}
- private PreviousIssue findLastIssueWithSameChecksumAndMessage(DefaultIssue newIssue, Collection<PreviousIssue> previousIssues) {
- for (PreviousIssue previousIssue : previousIssues) {
+ private ServerIssue findLastIssueWithSameChecksumAndMessage(DefaultIssue newIssue, Collection<ServerIssue> previousIssues) {
+ for (ServerIssue previousIssue : previousIssues) {
if (isSameChecksum(newIssue, previousIssue) && isSameMessage(newIssue, previousIssue)) {
return previousIssue;
}
@@ -264,15 +264,15 @@ public class IssueTracking implements BatchComponent {
return null;
}
- private PreviousIssue findLastIssueWithSameLineAndChecksum(DefaultIssue newIssue, IssueTrackingResult result) {
- Collection<PreviousIssue> sameRuleAndSameLineAndSameChecksum = result.unmatchedForRuleAndForLineAndForChecksum(newIssue.ruleKey(), newIssue.line(), newIssue.checksum());
+ private ServerIssue findLastIssueWithSameLineAndChecksum(DefaultIssue newIssue, IssueTrackingResult result) {
+ Collection<ServerIssue> sameRuleAndSameLineAndSameChecksum = result.unmatchedForRuleAndForLineAndForChecksum(newIssue.ruleKey(), newIssue.line(), newIssue.checksum());
if (!sameRuleAndSameLineAndSameChecksum.isEmpty()) {
return sameRuleAndSameLineAndSameChecksum.iterator().next();
}
return null;
}
- private boolean isNotAlreadyMapped(PreviousIssue previousIssue, IssueTrackingResult result) {
+ private boolean isNotAlreadyMapped(ServerIssue previousIssue, IssueTrackingResult result) {
return result.unmatched().contains(previousIssue);
}
@@ -280,19 +280,19 @@ public class IssueTracking implements BatchComponent {
return !result.isMatched(newIssue);
}
- private boolean isSameChecksum(DefaultIssue newIssue, PreviousIssue previousIssue) {
+ private boolean isSameChecksum(DefaultIssue newIssue, ServerIssue previousIssue) {
return Objects.equal(previousIssue.checksum(), newIssue.checksum());
}
- private boolean isSameLine(DefaultIssue newIssue, PreviousIssue previousIssue) {
+ private boolean isSameLine(DefaultIssue newIssue, ServerIssue previousIssue) {
return Objects.equal(previousIssue.line(), newIssue.line());
}
- private boolean isSameMessage(DefaultIssue newIssue, PreviousIssue previousIssue) {
+ private boolean isSameMessage(DefaultIssue newIssue, ServerIssue previousIssue) {
return Objects.equal(newIssue.message(), previousIssue.message());
}
- private void mapIssue(DefaultIssue issue, @Nullable PreviousIssue ref, IssueTrackingResult result) {
+ private void mapIssue(DefaultIssue issue, @Nullable ServerIssue ref, IssueTrackingResult result) {
if (ref != null) {
result.setMatch(issue, ref);
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTrackingDecorator.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTrackingDecorator.java
index c1ae052034c..406c9d0518f 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTrackingDecorator.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTrackingDecorator.java
@@ -125,7 +125,7 @@ public class IssueTrackingDecorator implements Decorator {
// issues = all the issues created by rule engines during this module scan and not excluded by filters
// all the issues that are not closed in db before starting this module scan, including manual issues
- Collection<PreviousIssue> dbOpenIssues = initialOpenIssues.selectAndRemoveIssues(resource.getEffectiveKey());
+ Collection<ServerIssue> dbOpenIssues = initialOpenIssues.selectAndRemoveIssues(resource.getEffectiveKey());
SourceHashHolder sourceHashHolder = null;
if (ResourceUtils.isFile(resource)) {
@@ -159,7 +159,7 @@ public class IssueTrackingDecorator implements Decorator {
@VisibleForTesting
protected void mergeMatched(IssueTrackingResult result) {
for (DefaultIssue issue : result.matched()) {
- IssueDto ref = ((PreviousIssueFromDb) result.matching(issue)).getDto();
+ IssueDto ref = ((ServerIssueFromDb) result.matching(issue)).getDto();
// invariant fields
issue.setKey(ref.getKee());
@@ -208,9 +208,9 @@ public class IssueTrackingDecorator implements Decorator {
}
}
- private void addUnmatched(Collection<PreviousIssue> unmatchedIssues, SourceHashHolder sourceHashHolder, Collection<DefaultIssue> issues) {
- for (PreviousIssue unmatchedIssue : unmatchedIssues) {
- IssueDto unmatchedDto = ((PreviousIssueFromDb) unmatchedIssue).getDto();
+ private void addUnmatched(Collection<ServerIssue> unmatchedIssues, SourceHashHolder sourceHashHolder, Collection<DefaultIssue> issues) {
+ for (ServerIssue unmatchedIssue : unmatchedIssues) {
+ IssueDto unmatchedDto = ((ServerIssueFromDb) unmatchedIssue).getDto();
DefaultIssue unmatched = unmatchedDto.toDefaultIssue();
if (StringUtils.isNotBlank(unmatchedDto.getReporter()) && !Issue.STATUS_CLOSED.equals(unmatchedDto.getStatus())) {
relocateManualIssue(unmatched, unmatchedDto, sourceHashHolder);
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTrackingResult.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTrackingResult.java
index f7b4e8d119e..8fe3549e66b 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTrackingResult.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/IssueTrackingResult.java
@@ -34,29 +34,29 @@ import java.util.HashMap;
import java.util.Map;
class IssueTrackingResult {
- private final Map<String, PreviousIssue> unmatchedByKey = new HashMap<>();
- private final Map<RuleKey, Map<String, PreviousIssue>> unmatchedByRuleAndKey = new HashMap<>();
- private final Map<RuleKey, Map<Integer, Multimap<String, PreviousIssue>>> unmatchedByRuleAndLineAndChecksum = new HashMap<>();
- private final Map<DefaultIssue, PreviousIssue> matched = Maps.newIdentityHashMap();
+ private final Map<String, ServerIssue> unmatchedByKey = new HashMap<>();
+ private final Map<RuleKey, Map<String, ServerIssue>> unmatchedByRuleAndKey = new HashMap<>();
+ private final Map<RuleKey, Map<Integer, Multimap<String, ServerIssue>>> unmatchedByRuleAndLineAndChecksum = new HashMap<>();
+ private final Map<DefaultIssue, ServerIssue> matched = Maps.newIdentityHashMap();
- Collection<PreviousIssue> unmatched() {
+ Collection<ServerIssue> unmatched() {
return unmatchedByKey.values();
}
- Map<String, PreviousIssue> unmatchedByKeyForRule(RuleKey ruleKey) {
- return unmatchedByRuleAndKey.containsKey(ruleKey) ? unmatchedByRuleAndKey.get(ruleKey) : Collections.<String, PreviousIssue>emptyMap();
+ Map<String, ServerIssue> unmatchedByKeyForRule(RuleKey ruleKey) {
+ return unmatchedByRuleAndKey.containsKey(ruleKey) ? unmatchedByRuleAndKey.get(ruleKey) : Collections.<String, ServerIssue>emptyMap();
}
- Collection<PreviousIssue> unmatchedForRuleAndForLineAndForChecksum(RuleKey ruleKey, @Nullable Integer line, @Nullable String checksum) {
+ Collection<ServerIssue> unmatchedForRuleAndForLineAndForChecksum(RuleKey ruleKey, @Nullable Integer line, @Nullable String checksum) {
if (!unmatchedByRuleAndLineAndChecksum.containsKey(ruleKey)) {
return Collections.emptyList();
}
- Map<Integer, Multimap<String, PreviousIssue>> unmatchedForRule = unmatchedByRuleAndLineAndChecksum.get(ruleKey);
+ Map<Integer, Multimap<String, ServerIssue>> unmatchedForRule = unmatchedByRuleAndLineAndChecksum.get(ruleKey);
Integer lineNotNull = line != null ? line : 0;
if (!unmatchedForRule.containsKey(lineNotNull)) {
return Collections.emptyList();
}
- Multimap<String, PreviousIssue> unmatchedForRuleAndLine = unmatchedForRule.get(lineNotNull);
+ Multimap<String, ServerIssue> unmatchedForRuleAndLine = unmatchedForRule.get(lineNotNull);
String checksumNotNull = StringUtils.defaultString(checksum, "");
if (!unmatchedForRuleAndLine.containsKey(checksumNotNull)) {
return Collections.emptyList();
@@ -72,34 +72,34 @@ class IssueTrackingResult {
return matched.containsKey(issue);
}
- PreviousIssue matching(DefaultIssue issue) {
+ ServerIssue matching(DefaultIssue issue) {
return matched.get(issue);
}
- void addUnmatched(PreviousIssue i) {
+ void addUnmatched(ServerIssue i) {
unmatchedByKey.put(i.key(), i);
RuleKey ruleKey = i.ruleKey();
if (!unmatchedByRuleAndKey.containsKey(ruleKey)) {
- unmatchedByRuleAndKey.put(ruleKey, new HashMap<String, PreviousIssue>());
- unmatchedByRuleAndLineAndChecksum.put(ruleKey, new HashMap<Integer, Multimap<String, PreviousIssue>>());
+ unmatchedByRuleAndKey.put(ruleKey, new HashMap<String, ServerIssue>());
+ unmatchedByRuleAndLineAndChecksum.put(ruleKey, new HashMap<Integer, Multimap<String, ServerIssue>>());
}
unmatchedByRuleAndKey.get(ruleKey).put(i.key(), i);
- Map<Integer, Multimap<String, PreviousIssue>> unmatchedForRule = unmatchedByRuleAndLineAndChecksum.get(ruleKey);
+ Map<Integer, Multimap<String, ServerIssue>> unmatchedForRule = unmatchedByRuleAndLineAndChecksum.get(ruleKey);
Integer lineNotNull = lineNotNull(i);
if (!unmatchedForRule.containsKey(lineNotNull)) {
- unmatchedForRule.put(lineNotNull, HashMultimap.<String, PreviousIssue>create());
+ unmatchedForRule.put(lineNotNull, HashMultimap.<String, ServerIssue>create());
}
- Multimap<String, PreviousIssue> unmatchedForRuleAndLine = unmatchedForRule.get(lineNotNull);
+ Multimap<String, ServerIssue> unmatchedForRuleAndLine = unmatchedForRule.get(lineNotNull);
String checksumNotNull = StringUtils.defaultString(i.checksum(), "");
unmatchedForRuleAndLine.put(checksumNotNull, i);
}
- private Integer lineNotNull(PreviousIssue i) {
+ private Integer lineNotNull(ServerIssue i) {
Integer line = i.line();
return line != null ? line : 0;
}
- void setMatch(DefaultIssue issue, PreviousIssue matching) {
+ void setMatch(DefaultIssue issue, ServerIssue matching) {
matched.put(issue, matching);
RuleKey ruleKey = matching.ruleKey();
unmatchedByRuleAndKey.get(ruleKey).remove(matching.key());
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/LocalIssueTracking.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/LocalIssueTracking.java
index c4d9a65769f..7d67696196e 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/LocalIssueTracking.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/LocalIssueTracking.java
@@ -24,6 +24,7 @@ import com.google.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.BatchComponent;
+import org.sonar.api.batch.AnalysisMode;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.rule.ActiveRule;
import org.sonar.api.batch.rule.ActiveRules;
@@ -39,11 +40,13 @@ import org.sonar.batch.issue.IssueCache;
import org.sonar.batch.protocol.input.ProjectRepositories;
import org.sonar.batch.scan.LastLineHashes;
import org.sonar.batch.scan.filesystem.InputPathCache;
+import org.sonar.core.component.ComponentKeys;
import org.sonar.core.issue.IssueUpdater;
import org.sonar.core.issue.workflow.IssueWorkflow;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Date;
public class LocalIssueTracking implements BatchComponent {
@@ -58,12 +61,14 @@ public class LocalIssueTracking implements BatchComponent {
private final ActiveRules activeRules;
private final InputPathCache inputPathCache;
private final ResourceCache resourceCache;
- private final PreviousIssueRepository previousIssueCache;
+ private final ServerIssueRepository serverIssueRepository;
private final ProjectRepositories projectRepositories;
+ private final AnalysisMode analysisMode;
public LocalIssueTracking(ResourceCache resourceCache, IssueCache issueCache, IssueTracking tracking,
LastLineHashes lastLineHashes, IssueWorkflow workflow, IssueUpdater updater,
- ActiveRules activeRules, InputPathCache inputPathCache, PreviousIssueRepository previousIssueCache, ProjectRepositories projectRepositories) {
+ ActiveRules activeRules, InputPathCache inputPathCache, ServerIssueRepository serverIssueRepository,
+ ProjectRepositories projectRepositories, AnalysisMode analysisMode) {
this.resourceCache = resourceCache;
this.issueCache = issueCache;
this.tracking = tracking;
@@ -71,8 +76,9 @@ public class LocalIssueTracking implements BatchComponent {
this.workflow = workflow;
this.updater = updater;
this.inputPathCache = inputPathCache;
- this.previousIssueCache = previousIssueCache;
+ this.serverIssueRepository = serverIssueRepository;
this.projectRepositories = projectRepositories;
+ this.analysisMode = analysisMode;
this.changeContext = IssueChangeContext.createScan(((Project) resourceCache.getRoot().resource()).getAnalysisDate());
this.activeRules = activeRules;
}
@@ -83,7 +89,7 @@ public class LocalIssueTracking implements BatchComponent {
return;
}
- previousIssueCache.load();
+ serverIssueRepository.load();
for (BatchResource component : resourceCache.all()) {
trackIssues(component);
@@ -99,10 +105,15 @@ public class LocalIssueTracking implements BatchComponent {
issueCache.clear(component.resource().getEffectiveKey());
// issues = all the issues created by rule engines during this module scan and not excluded by filters
+ if (analysisMode.isIncremental() && !component.isFile()) {
+ // No need to report issues on project or directories in preview mode since it is likely to be wrong anyway
+ return;
+ }
+
// all the issues that are not closed in db before starting this module scan, including manual issues
- Collection<PreviousIssue> previousIssues = new ArrayList<>();
- for (org.sonar.batch.protocol.input.issues.PreviousIssue previousIssue : previousIssueCache.byComponent(component)) {
- previousIssues.add(new PreviousIssueFromWs(previousIssue));
+ Collection<ServerIssue> previousIssues = new ArrayList<>();
+ for (org.sonar.batch.protocol.input.BatchInput.ServerIssue previousIssue : serverIssueRepository.byComponent(component)) {
+ previousIssues.add(new ServerIssueFromWs(previousIssue));
}
SourceHashHolder sourceHashHolder = null;
@@ -135,10 +146,10 @@ public class LocalIssueTracking implements BatchComponent {
@VisibleForTesting
protected void mergeMatched(IssueTrackingResult result) {
for (DefaultIssue issue : result.matched()) {
- org.sonar.batch.protocol.input.issues.PreviousIssue ref = ((PreviousIssueFromWs) result.matching(issue)).getDto();
+ org.sonar.batch.protocol.input.BatchInput.ServerIssue ref = ((ServerIssueFromWs) result.matching(issue)).getDto();
// invariant fields
- issue.setKey(ref.key());
+ issue.setKey(ref.getKey());
// non-persisted fields
issue.setNew(false);
@@ -146,23 +157,23 @@ public class LocalIssueTracking implements BatchComponent {
issue.setOnDisabledRule(false);
// fields to update with old values
- issue.setResolution(ref.resolution());
- issue.setStatus(ref.status());
- issue.setAssignee(ref.assigneeLogin());
- issue.setCreationDate(ref.creationDate());
+ issue.setResolution(ref.hasResolution() ? ref.getResolution() : null);
+ issue.setStatus(ref.getStatus());
+ issue.setAssignee(ref.hasAssigneeLogin() ? ref.getAssigneeLogin() : null);
+ issue.setCreationDate(new Date(ref.getCreationDate()));
- if (ref.isManualSeverity()) {
+ if (ref.getManualSeverity()) {
// Severity overriden by user
- issue.setSeverity(ref.severity());
+ issue.setSeverity(ref.getSeverity().name());
}
}
}
- private void addUnmatched(Collection<PreviousIssue> unmatchedIssues, SourceHashHolder sourceHashHolder, Collection<DefaultIssue> issues) {
- for (PreviousIssue unmatchedIssue : unmatchedIssues) {
- org.sonar.batch.protocol.input.issues.PreviousIssue unmatchedPreviousIssue = ((PreviousIssueFromWs) unmatchedIssue).getDto();
+ private void addUnmatched(Collection<ServerIssue> unmatchedIssues, SourceHashHolder sourceHashHolder, Collection<DefaultIssue> issues) {
+ for (ServerIssue unmatchedIssue : unmatchedIssues) {
+ org.sonar.batch.protocol.input.BatchInput.ServerIssue unmatchedPreviousIssue = ((ServerIssueFromWs) unmatchedIssue).getDto();
DefaultIssue unmatched = toUnmatchedIssue(unmatchedPreviousIssue);
- if (unmatchedIssue.ruleKey().isManual() && !Issue.STATUS_CLOSED.equals(unmatchedPreviousIssue.status())) {
+ if (unmatchedIssue.ruleKey().isManual() && !Issue.STATUS_CLOSED.equals(unmatchedPreviousIssue.getStatus())) {
relocateManualIssue(unmatched, unmatchedIssue, sourceHashHolder);
}
updateUnmatchedIssue(unmatched, false /* manual issues can be kept open */);
@@ -171,26 +182,26 @@ public class LocalIssueTracking implements BatchComponent {
}
private void addIssuesOnDeletedComponents(Collection<DefaultIssue> issues) {
- for (org.sonar.batch.protocol.input.issues.PreviousIssue previous : previousIssueCache.issuesOnMissingComponents()) {
+ for (org.sonar.batch.protocol.input.BatchInput.ServerIssue previous : serverIssueRepository.issuesOnMissingComponents()) {
DefaultIssue dead = toUnmatchedIssue(previous);
updateUnmatchedIssue(dead, true);
issues.add(dead);
}
}
- private DefaultIssue toUnmatchedIssue(org.sonar.batch.protocol.input.issues.PreviousIssue previous) {
+ private DefaultIssue toUnmatchedIssue(org.sonar.batch.protocol.input.BatchInput.ServerIssue serverIssue) {
DefaultIssue issue = new DefaultIssue();
- issue.setKey(previous.key());
- issue.setStatus(previous.status());
- issue.setResolution(previous.resolution());
- issue.setMessage(previous.message());
- issue.setLine(previous.line());
- issue.setSeverity(previous.severity());
- issue.setAssignee(previous.assigneeLogin());
- issue.setComponentKey(previous.componentKey());
- issue.setManualSeverity(previous.isManualSeverity());
- issue.setCreationDate(previous.creationDate());
- issue.setRuleKey(RuleKey.of(previous.ruleRepo(), previous.ruleKey()));
+ issue.setKey(serverIssue.getKey());
+ issue.setStatus(serverIssue.getStatus());
+ issue.setResolution(serverIssue.hasResolution() ? serverIssue.getResolution() : null);
+ issue.setMessage(serverIssue.hasMsg() ? serverIssue.getMsg() : null);
+ issue.setLine(serverIssue.hasLine() ? serverIssue.getLine() : null);
+ issue.setSeverity(serverIssue.getSeverity().name());
+ issue.setAssignee(serverIssue.hasAssigneeLogin() ? serverIssue.getAssigneeLogin() : null);
+ issue.setComponentKey(ComponentKeys.createEffectiveKey(serverIssue.getModuleKey(), serverIssue.hasPath() ? serverIssue.getPath() : null));
+ issue.setManualSeverity(serverIssue.getManualSeverity());
+ issue.setCreationDate(new Date(serverIssue.getCreationDate()));
+ issue.setRuleKey(RuleKey.of(serverIssue.getRuleRepository(), serverIssue.getRuleKey()));
issue.setNew(false);
return issue;
}
@@ -209,7 +220,7 @@ public class LocalIssueTracking implements BatchComponent {
issue.setOnDisabledRule(isRemovedRule);
}
- private void relocateManualIssue(DefaultIssue newIssue, PreviousIssue oldIssue, SourceHashHolder sourceHashHolder) {
+ private void relocateManualIssue(DefaultIssue newIssue, ServerIssue oldIssue, SourceHashHolder sourceHashHolder) {
Integer previousLine = oldIssue.line();
if (previousLine == null) {
return;
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/PreviousIssueRepository.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/PreviousIssueRepository.java
deleted file mode 100644
index ce9ff46803f..00000000000
--- a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/PreviousIssueRepository.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.batch.issue.tracking;
-
-import com.google.common.base.Function;
-import org.sonar.api.BatchComponent;
-import org.sonar.api.batch.InstantiationStrategy;
-import org.sonar.api.batch.bootstrap.ProjectReactor;
-import org.sonar.api.utils.log.Logger;
-import org.sonar.api.utils.log.Loggers;
-import org.sonar.api.utils.log.Profiler;
-import org.sonar.batch.index.BatchResource;
-import org.sonar.batch.index.Cache;
-import org.sonar.batch.index.Caches;
-import org.sonar.batch.index.ResourceCache;
-import org.sonar.batch.protocol.input.issues.PreviousIssue;
-import org.sonar.batch.repository.PreviousIssuesLoader;
-
-import javax.annotation.Nullable;
-
-@InstantiationStrategy(InstantiationStrategy.PER_BATCH)
-public class PreviousIssueRepository implements BatchComponent {
-
- private static final Logger LOG = Loggers.get(PreviousIssueRepository.class);
-
- private final Caches caches;
- private Cache<PreviousIssue> issuesCache;
- private final PreviousIssuesLoader previousIssuesLoader;
- private final ProjectReactor reactor;
- private final ResourceCache resourceCache;
-
- public PreviousIssueRepository(Caches caches, PreviousIssuesLoader previousIssuesLoader, ProjectReactor reactor, ResourceCache resourceCache) {
- this.caches = caches;
- this.previousIssuesLoader = previousIssuesLoader;
- this.reactor = reactor;
- this.resourceCache = resourceCache;
- }
-
- public void load() {
- Profiler profiler = Profiler.create(LOG).startInfo("Load previous issues");
- this.issuesCache = caches.createCache("previousIssues");
- previousIssuesLoader.load(reactor, new Function<PreviousIssue, Void>() {
-
- @Override
- public Void apply(@Nullable PreviousIssue issue) {
- if (issue == null) {
- return null;
- }
- String componentKey = issue.componentKey();
- BatchResource r = resourceCache.get(componentKey);
- if (r == null) {
- // Deleted resource
- issuesCache.put(0, issue.key(), issue);
- } else {
- issuesCache.put(r.batchId(), issue.key(), issue);
- }
- return null;
- }
- });
- profiler.stopDebug();
- }
-
- public Iterable<PreviousIssue> byComponent(BatchResource component) {
- return issuesCache.values(component.batchId());
- }
-
- public Iterable<PreviousIssue> issuesOnMissingComponents() {
- return issuesCache.values(0);
- }
-}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/PreviousIssue.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/ServerIssue.java
index dcef8caaa5a..5c492edefe8 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/PreviousIssue.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/ServerIssue.java
@@ -23,7 +23,7 @@ import org.sonar.api.rule.RuleKey;
import javax.annotation.CheckForNull;
-public interface PreviousIssue {
+public interface ServerIssue {
String key();
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/PreviousIssueFromDb.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/ServerIssueFromDb.java
index f20f420def4..d858d3a745f 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/PreviousIssueFromDb.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/ServerIssueFromDb.java
@@ -22,11 +22,11 @@ package org.sonar.batch.issue.tracking;
import org.sonar.api.rule.RuleKey;
import org.sonar.core.issue.db.IssueDto;
-public class PreviousIssueFromDb implements PreviousIssue {
+public class ServerIssueFromDb implements ServerIssue {
private IssueDto dto;
- public PreviousIssueFromDb(IssueDto dto) {
+ public ServerIssueFromDb(IssueDto dto) {
this.dto = dto;
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/PreviousIssueFromWs.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/ServerIssueFromWs.java
index a9a435abb8c..116c2aa90fd 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/PreviousIssueFromWs.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/ServerIssueFromWs.java
@@ -21,41 +21,41 @@ package org.sonar.batch.issue.tracking;
import org.sonar.api.rule.RuleKey;
-public class PreviousIssueFromWs implements PreviousIssue {
+public class ServerIssueFromWs implements ServerIssue {
- private org.sonar.batch.protocol.input.issues.PreviousIssue dto;
+ private org.sonar.batch.protocol.input.BatchInput.ServerIssue dto;
- public PreviousIssueFromWs(org.sonar.batch.protocol.input.issues.PreviousIssue dto) {
+ public ServerIssueFromWs(org.sonar.batch.protocol.input.BatchInput.ServerIssue dto) {
this.dto = dto;
}
- public org.sonar.batch.protocol.input.issues.PreviousIssue getDto() {
+ public org.sonar.batch.protocol.input.BatchInput.ServerIssue getDto() {
return dto;
}
@Override
public String key() {
- return dto.key();
+ return dto.getKey();
}
@Override
public RuleKey ruleKey() {
- return RuleKey.of(dto.ruleRepo(), dto.ruleKey());
+ return RuleKey.of(dto.getRuleRepository(), dto.getRuleKey());
}
@Override
public String checksum() {
- return dto.checksum();
+ return dto.hasChecksum() ? dto.getChecksum() : null;
}
@Override
public Integer line() {
- return dto.line();
+ return dto.hasLine() ? dto.getLine() : null;
}
@Override
public String message() {
- return dto.message();
+ return dto.hasMsg() ? dto.getMsg() : null;
}
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/ServerIssueRepository.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/ServerIssueRepository.java
new file mode 100644
index 00000000000..6fa0e45c368
--- /dev/null
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/ServerIssueRepository.java
@@ -0,0 +1,122 @@
+/*
+ * 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.issue.tracking;
+
+import com.google.common.base.Function;
+import org.sonar.api.BatchComponent;
+import org.sonar.api.batch.AnalysisMode;
+import org.sonar.api.batch.InstantiationStrategy;
+import org.sonar.api.batch.bootstrap.ProjectReactor;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
+import org.sonar.api.utils.log.Profiler;
+import org.sonar.batch.index.BatchResource;
+import org.sonar.batch.index.Cache;
+import org.sonar.batch.index.Caches;
+import org.sonar.batch.index.ResourceCache;
+import org.sonar.batch.protocol.input.BatchInput.ServerIssue;
+import org.sonar.batch.repository.ServerIssuesLoader;
+import org.sonar.core.component.ComponentKeys;
+
+import javax.annotation.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@InstantiationStrategy(InstantiationStrategy.PER_BATCH)
+public class ServerIssueRepository implements BatchComponent {
+
+ private static final Logger LOG = Loggers.get(ServerIssueRepository.class);
+
+ private final Caches caches;
+ private Cache<ServerIssue> issuesCache;
+ private final ServerIssuesLoader previousIssuesLoader;
+ private final ProjectReactor reactor;
+ private final ResourceCache resourceCache;
+ private final AnalysisMode analysisMode;
+
+ public ServerIssueRepository(Caches caches, ServerIssuesLoader previousIssuesLoader, ProjectReactor reactor, ResourceCache resourceCache, AnalysisMode analysisMode) {
+ this.caches = caches;
+ this.previousIssuesLoader = previousIssuesLoader;
+ this.reactor = reactor;
+ this.resourceCache = resourceCache;
+ this.analysisMode = analysisMode;
+ }
+
+ public void load() {
+ if (analysisMode.isIncremental()) {
+ return;
+ }
+ Profiler profiler = Profiler.create(LOG).startInfo("Load server issues");
+ this.issuesCache = caches.createCache("previousIssues");
+ caches.registerValueCoder(ServerIssue.class, new ServerIssueValueCoder());
+ previousIssuesLoader.load(reactor.getRoot().getKeyWithBranch(), new Function<ServerIssue, Void>() {
+
+ @Override
+ public Void apply(@Nullable ServerIssue issue) {
+ if (issue == null) {
+ return null;
+ }
+ String componentKey = ComponentKeys.createEffectiveKey(issue.getModuleKey(), issue.hasPath() ? issue.getPath() : null);
+ BatchResource r = resourceCache.get(componentKey);
+ if (r == null) {
+ // Deleted resource
+ issuesCache.put(0, issue.getKey(), issue);
+ } else {
+ issuesCache.put(r.batchId(), issue.getKey(), issue);
+ }
+ return null;
+ }
+ }, false);
+ profiler.stopDebug();
+ }
+
+ public Iterable<ServerIssue> byComponent(BatchResource component) {
+ if (analysisMode.isIncremental()) {
+ if (!component.isFile()) {
+ throw new UnsupportedOperationException("Incremental mode should only get issues on files");
+ }
+ Profiler profiler = Profiler.create(LOG).startInfo("Load server issues for " + component.resource().getPath());
+ final List<ServerIssue> result = new ArrayList<>();
+ previousIssuesLoader.load(component.key(), new Function<ServerIssue, Void>() {
+
+ @Override
+ public Void apply(@Nullable ServerIssue issue) {
+ if (issue == null) {
+ return null;
+ }
+ result.add(issue);
+ return null;
+ }
+ }, true);
+ profiler.stopDebug();
+ return result;
+ } else {
+ return issuesCache.values(component.batchId());
+ }
+ }
+
+ public Iterable<ServerIssue> issuesOnMissingComponents() {
+ if (analysisMode.isIncremental()) {
+ throw new UnsupportedOperationException("Only issues of analyzed components are loaded in incremental mode");
+ }
+ return issuesCache.values(0);
+ }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/ServerIssueValueCoder.java b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/ServerIssueValueCoder.java
new file mode 100644
index 00000000000..321d09a852b
--- /dev/null
+++ b/sonar-batch/src/main/java/org/sonar/batch/issue/tracking/ServerIssueValueCoder.java
@@ -0,0 +1,47 @@
+/*
+ * 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.issue.tracking;
+
+import com.persistit.Value;
+import com.persistit.encoding.CoderContext;
+import com.persistit.encoding.ValueCoder;
+import com.persistit.exception.ConversionException;
+import org.sonar.batch.protocol.input.BatchInput.ServerIssue;
+
+import java.io.IOException;
+
+public class ServerIssueValueCoder implements ValueCoder {
+
+ @Override
+ public void put(Value value, Object object, CoderContext context) throws ConversionException {
+ ServerIssue issue = (ServerIssue) object;
+ value.putByteArray(issue.toByteArray());
+ }
+
+ @Override
+ public Object get(Value value, Class<?> clazz, CoderContext context) throws ConversionException {
+ try {
+ return ServerIssue.parseFrom(value.getByteArray());
+ } catch (IOException e) {
+ throw new IllegalStateException("Unable to read issue from cache", e);
+ }
+ }
+
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java b/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java
index 5f5f74b3a1a..f7517a7be8f 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java
@@ -34,13 +34,14 @@ import org.sonar.batch.bootstrap.TaskProperties;
import org.sonar.batch.bootstrapper.Batch;
import org.sonar.batch.bootstrapper.EnvironmentInformation;
import org.sonar.batch.protocol.input.ActiveRule;
+import org.sonar.batch.protocol.input.BatchInput.ServerIssue;
import org.sonar.batch.protocol.input.FileData;
import org.sonar.batch.protocol.input.GlobalRepositories;
import org.sonar.batch.protocol.input.ProjectRepositories;
-import org.sonar.batch.protocol.input.issues.PreviousIssue;
import org.sonar.batch.repository.GlobalRepositoriesLoader;
-import org.sonar.batch.repository.PreviousIssuesLoader;
import org.sonar.batch.repository.ProjectRepositoriesLoader;
+import org.sonar.batch.repository.ServerIssuesLoader;
+import org.sonar.core.component.ComponentKeys;
import org.sonar.core.plugins.DefaultPluginMetadata;
import org.sonar.core.plugins.RemotePlugin;
@@ -75,7 +76,7 @@ public class BatchMediumTester {
private final FakeGlobalRepositoriesLoader globalRefProvider = new FakeGlobalRepositoriesLoader();
private final FakeProjectRepositoriesLoader projectRefProvider = new FakeProjectRepositoriesLoader();
private final FakePluginsRepository pluginsReferential = new FakePluginsRepository();
- private final FakePreviousIssuesLoader previousIssues = new FakePreviousIssuesLoader();
+ private final FakeServerIssuesLoader serverIssues = new FakeServerIssuesLoader();
private final Map<String, String> bootstrapProperties = new HashMap<String, String>();
public BatchMediumTester build() {
@@ -135,8 +136,8 @@ public class BatchMediumTester {
return this;
}
- public BatchMediumTesterBuilder addPreviousIssue(PreviousIssue issue) {
- previousIssues.getPreviousIssues().add(issue);
+ public BatchMediumTesterBuilder mockServerIssue(ServerIssue issue) {
+ serverIssues.getServerIssues().add(issue);
return this;
}
@@ -158,7 +159,7 @@ public class BatchMediumTester {
builder.pluginsReferential,
builder.globalRefProvider,
builder.projectRefProvider,
- builder.previousIssues,
+ builder.serverIssues,
new DefaultDebtModel())
.setBootstrapProperties(builder.bootstrapProperties)
.build();
@@ -305,18 +306,20 @@ public class BatchMediumTester {
}
- private static class FakePreviousIssuesLoader implements PreviousIssuesLoader {
+ private static class FakeServerIssuesLoader implements ServerIssuesLoader {
- List<PreviousIssue> previousIssues = new ArrayList<>();
+ private List<ServerIssue> serverIssues = new ArrayList<>();
- public List<PreviousIssue> getPreviousIssues() {
- return previousIssues;
+ public List<ServerIssue> getServerIssues() {
+ return serverIssues;
}
@Override
- public void load(ProjectReactor reactor, Function<PreviousIssue, Void> consumer) {
- for (PreviousIssue previousIssue : previousIssues) {
- consumer.apply(previousIssue);
+ public void load(String componentKey, Function<ServerIssue, Void> consumer, boolean incremental) {
+ for (ServerIssue serverIssue : serverIssues) {
+ if (!incremental || ComponentKeys.createEffectiveKey(serverIssue.getModuleKey(), serverIssue.hasPath() ? serverIssue.getPath() : null).equals(componentKey)) {
+ consumer.apply(serverIssue);
+ }
}
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultPreviousIssuesLoader.java b/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultServerIssuesLoader.java
index f9ea0792c7f..8f32995522a 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultPreviousIssuesLoader.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/repository/DefaultServerIssuesLoader.java
@@ -19,34 +19,31 @@
*/
package org.sonar.batch.repository;
-import com.google.common.base.Charsets;
import com.google.common.base.Function;
import com.google.common.io.InputSupplier;
-import org.sonar.api.batch.bootstrap.ProjectReactor;
import org.sonar.api.utils.HttpDownloader;
import org.sonar.batch.bootstrap.ServerClient;
-import org.sonar.batch.protocol.input.issues.PreviousIssue;
-import org.sonar.batch.protocol.input.issues.PreviousIssueHelper;
+import org.sonar.batch.protocol.input.BatchInput.ServerIssue;
import java.io.IOException;
import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-public class DefaultPreviousIssuesLoader implements PreviousIssuesLoader {
+public class DefaultServerIssuesLoader implements ServerIssuesLoader {
private final ServerClient serverClient;
- public DefaultPreviousIssuesLoader(ServerClient serverClient) {
+ public DefaultServerIssuesLoader(ServerClient serverClient) {
this.serverClient = serverClient;
}
@Override
- public void load(ProjectReactor reactor, Function<PreviousIssue, Void> consumer) {
- InputSupplier<InputStream> request = serverClient.doRequest("/batch/issues?key=" + ServerClient.encodeForUrl(reactor.getRoot().getKeyWithBranch()), "GET", null);
- try (InputStream is = request.getInput(); Reader reader = new InputStreamReader(is, Charsets.UTF_8)) {
- for (PreviousIssue issue : PreviousIssueHelper.getIssues(reader)) {
- consumer.apply(issue);
+ public void load(String componentKey, Function<ServerIssue, Void> consumer, boolean incremental) {
+ InputSupplier<InputStream> request = serverClient.doRequest("/batch/issues?key=" + ServerClient.encodeForUrl(componentKey), "GET", null);
+ try (InputStream is = request.getInput()) {
+ ServerIssue previousIssue = ServerIssue.parseDelimitedFrom(is);
+ while (previousIssue != null) {
+ consumer.apply(previousIssue);
+ previousIssue = ServerIssue.parseDelimitedFrom(is);
}
} catch (HttpDownloader.HttpException e) {
throw serverClient.handleHttpException(e);
diff --git a/sonar-batch/src/main/java/org/sonar/batch/repository/PreviousIssuesLoader.java b/sonar-batch/src/main/java/org/sonar/batch/repository/ServerIssuesLoader.java
index fe706da3e73..eae1d2fb3ea 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/repository/PreviousIssuesLoader.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/repository/ServerIssuesLoader.java
@@ -20,11 +20,10 @@
package org.sonar.batch.repository;
import com.google.common.base.Function;
-import org.sonar.api.batch.bootstrap.ProjectReactor;
-import org.sonar.batch.protocol.input.issues.PreviousIssue;
+import org.sonar.batch.protocol.input.BatchInput.ServerIssue;
-public interface PreviousIssuesLoader {
+public interface ServerIssuesLoader {
- void load(ProjectReactor reactor, Function<PreviousIssue, Void> consumer);
+ void load(String componentKey, Function<ServerIssue, Void> consumer, boolean incremental);
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java
index a2f46a03fe4..0cc044e2036 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectScanContainer.java
@@ -62,7 +62,7 @@ import org.sonar.batch.issue.DefaultProjectIssues;
import org.sonar.batch.issue.IssueCache;
import org.sonar.batch.issue.tracking.InitialOpenIssuesStack;
import org.sonar.batch.issue.tracking.LocalIssueTracking;
-import org.sonar.batch.issue.tracking.PreviousIssueRepository;
+import org.sonar.batch.issue.tracking.ServerIssueRepository;
import org.sonar.batch.mediumtest.ScanTaskObservers;
import org.sonar.batch.phases.GraphPersister;
import org.sonar.batch.profiling.PhasesSumUpTimeProfiler;
@@ -165,7 +165,7 @@ public class ProjectScanContainer extends ComponentContainer {
DefaultProjectIssues.class,
IssueChangelogDebtCalculator.class,
LocalIssueTracking.class,
- PreviousIssueRepository.class,
+ ServerIssueRepository.class,
// tests
TestPlanPerspectiveLoader.class,
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/report/ConsoleReport.java b/sonar-batch/src/main/java/org/sonar/batch/scan/report/ConsoleReport.java
index 4e50af72e52..88493d10d64 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan/report/ConsoleReport.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan/report/ConsoleReport.java
@@ -21,42 +21,43 @@ package org.sonar.batch.scan.report;
import com.google.common.annotations.VisibleForTesting;
import org.apache.commons.lang.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.sonar.api.Properties;
import org.sonar.api.Property;
import org.sonar.api.PropertyType;
import org.sonar.api.config.Settings;
import org.sonar.api.issue.internal.DefaultIssue;
import org.sonar.api.rule.Severity;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
import org.sonar.batch.issue.IssueCache;
+import org.sonar.batch.scan.filesystem.InputPathCache;
@Properties({
@Property(key = ConsoleReport.CONSOLE_REPORT_ENABLED_KEY, name = "Enable console report", description = "Set this to true to generate a report in console output",
type = PropertyType.BOOLEAN, defaultValue = "false")})
public class ConsoleReport implements Reporter {
- private static final Logger LOG = LoggerFactory.getLogger(ConsoleReport.class);
+
+ @VisibleForTesting
+ public static final String HEADER = "------------- Issues Report -------------";
+
+ private static final Logger LOG = Loggers.get(ConsoleReport.class);
public static final String CONSOLE_REPORT_ENABLED_KEY = "sonar.issuesReport.console.enable";
private static final int LEFT_PAD = 10;
private Settings settings;
- private Logger logger;
-
private IssueCache issueCache;
-
- public ConsoleReport(Settings settings, IssueCache issueCache) {
- this(settings, issueCache, LOG);
- }
+ private InputPathCache inputPathCache;
@VisibleForTesting
- public ConsoleReport(Settings settings, IssueCache issueCache, Logger logger) {
+ public ConsoleReport(Settings settings, IssueCache issueCache, InputPathCache inputPathCache) {
this.settings = settings;
this.issueCache = issueCache;
- this.logger = logger;
+ this.inputPathCache = inputPathCache;
}
private static class Report {
+ boolean noFile = false;
int totalNewIssues = 0;
int newBlockerIssues = 0;
int newCriticalIssues = 0;
@@ -88,24 +89,40 @@ public class ConsoleReport implements Reporter {
}
}
}
+
+ public void setNoFile(boolean value) {
+ this.noFile = value;
+ }
}
@Override
public void execute() {
if (settings.getBoolean(CONSOLE_REPORT_ENABLED_KEY)) {
Report r = new Report();
+ r.setNoFile(!inputPathCache.allFiles().iterator().hasNext());
for (DefaultIssue issue : issueCache.all()) {
r.process(issue);
}
- printNewIssues(r);
+ printReport(r);
}
}
- public void printNewIssues(Report r) {
+ public void printReport(Report r) {
StringBuilder sb = new StringBuilder();
+ sb.append("\n\n" + HEADER + "\n\n");
+ if (r.noFile) {
+ sb.append(" No file analyzed\n");
+ } else {
+ printNewIssues(r, sb);
+ }
+ sb.append("\n-------------------------------------------\n\n");
+
+ LOG.info(sb.toString());
+ }
+
+ private void printNewIssues(Report r, StringBuilder sb) {
int newIssues = r.totalNewIssues;
- sb.append("\n\n------------- Issues Report -------------\n\n");
if (newIssues > 0) {
sb.append(StringUtils.leftPad("+" + newIssues, LEFT_PAD)).append(" issue" + (newIssues > 1 ? "s" : "")).append("\n\n");
printNewIssues(sb, r.newBlockerIssues, Severity.BLOCKER, "blocking");
@@ -116,9 +133,6 @@ public class ConsoleReport implements Reporter {
} else {
sb.append(" No new issue").append("\n");
}
- sb.append("\n-------------------------------------------\n\n");
-
- logger.info(sb.toString());
}
private void printNewIssues(StringBuilder sb, int issueCount, String severity, String severityLabel) {
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/report/IssuesReport.java b/sonar-batch/src/main/java/org/sonar/batch/scan/report/IssuesReport.java
index a4513f65929..fb23eed4c21 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan/report/IssuesReport.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan/report/IssuesReport.java
@@ -35,6 +35,7 @@ public class IssuesReport {
public static final int TOO_MANY_ISSUES_THRESHOLD = 1000;
private String title;
private Date date;
+ private boolean noFile;
private final ReportSummary summary = new ReportSummary();
private final Map<BatchResource, ResourceReport> resourceReportsByResource = Maps.newLinkedHashMap();
@@ -61,6 +62,14 @@ public class IssuesReport {
this.date = date;
}
+ public boolean isNoFile() {
+ return noFile;
+ }
+
+ public void setNoFile(boolean noFile) {
+ this.noFile = noFile;
+ }
+
public Map<BatchResource, ResourceReport> getResourceReportsByResource() {
return resourceReportsByResource;
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/report/IssuesReportBuilder.java b/sonar-batch/src/main/java/org/sonar/batch/scan/report/IssuesReportBuilder.java
index 12dd08e79c0..36af32c9c92 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan/report/IssuesReportBuilder.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan/report/IssuesReportBuilder.java
@@ -33,6 +33,7 @@ import org.sonar.batch.ProjectTree;
import org.sonar.batch.index.BatchResource;
import org.sonar.batch.index.ResourceCache;
import org.sonar.batch.issue.IssueCache;
+import org.sonar.batch.scan.filesystem.InputPathCache;
import javax.annotation.CheckForNull;
@@ -44,17 +45,20 @@ public class IssuesReportBuilder implements BatchExtension {
private final RuleFinder ruleFinder;
private final ResourceCache resourceCache;
private final ProjectTree projectTree;
+ private final InputPathCache inputPathCache;
- public IssuesReportBuilder(IssueCache issueCache, RuleFinder ruleFinder, ResourceCache resourceCache, ProjectTree projectTree) {
+ public IssuesReportBuilder(IssueCache issueCache, RuleFinder ruleFinder, ResourceCache resourceCache, ProjectTree projectTree, InputPathCache inputPathCache) {
this.issueCache = issueCache;
this.ruleFinder = ruleFinder;
this.resourceCache = resourceCache;
this.projectTree = projectTree;
+ this.inputPathCache = inputPathCache;
}
public IssuesReport buildReport() {
Project project = projectTree.getRootProject();
IssuesReport issuesReport = new IssuesReport();
+ issuesReport.setNoFile(!inputPathCache.allFiles().iterator().hasNext());
issuesReport.setTitle(project.getName());
issuesReport.setDate(project.getAnalysisDate());
diff --git a/sonar-batch/src/main/resources/org/sonar/batch/scan/report/issuesreport.ftl b/sonar-batch/src/main/resources/org/sonar/batch/scan/report/issuesreport.ftl
index 5f757cccd30..86ba1631eaa 100644
--- a/sonar-batch/src/main/resources/org/sonar/batch/scan/report/issuesreport.ftl
+++ b/sonar-batch/src/main/resources/org/sonar/batch/scan/report/issuesreport.ftl
@@ -168,6 +168,11 @@
<div class="subtitle">${report.getTitle()} - ${report.getDate()?datetime}</div>
</div>
+<#if report.isNoFile()>
+<div id="content">
+ <div class="banner">No file analyzed</div>
+</div>
+<#else>
<div id="content">
<#if !complete>
@@ -452,5 +457,6 @@
refreshFilters(true);
});
</script>
+</#if>
</body>
</html>
diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/DefaultAnalysisModeTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/DefaultAnalysisModeTest.java
index f4d129bb4ff..65c7d548b9a 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/DefaultAnalysisModeTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/DefaultAnalysisModeTest.java
@@ -20,10 +20,12 @@
package org.sonar.batch.bootstrap;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
import org.junit.Test;
import org.sonar.api.CoreProperties;
import java.util.Collections;
+import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
@@ -31,13 +33,12 @@ public class DefaultAnalysisModeTest {
@Test
public void regular_analysis_by_default() {
- DefaultAnalysisMode mode = new DefaultAnalysisMode(new BootstrapProperties(Collections.<String, String>emptyMap()));
+ DefaultAnalysisMode mode = new DefaultAnalysisMode(Collections.<String, String>emptyMap());
assertThat(mode.isPreview()).isFalse();
assertThat(mode.isIncremental()).isFalse();
- BootstrapProperties bootstrapProps = new BootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, "pouet"));
- mode = new DefaultAnalysisMode(bootstrapProps);
+ mode = new DefaultAnalysisMode(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, "pouet"));
assertThat(mode.isPreview()).isFalse();
assertThat(mode.isIncremental()).isFalse();
@@ -45,8 +46,7 @@ public class DefaultAnalysisModeTest {
@Test
public void support_analysis_mode() {
- BootstrapProperties bootstrapProps = new BootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_ANALYSIS));
- DefaultAnalysisMode mode = new DefaultAnalysisMode(bootstrapProps);
+ DefaultAnalysisMode mode = new DefaultAnalysisMode(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_ANALYSIS));
assertThat(mode.isPreview()).isFalse();
assertThat(mode.isIncremental()).isFalse();
@@ -54,30 +54,29 @@ public class DefaultAnalysisModeTest {
@Test
public void support_preview_mode() {
- BootstrapProperties bootstrapProps = new BootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_PREVIEW));
- DefaultAnalysisMode mode = new DefaultAnalysisMode(bootstrapProps);
+ Map<String, String> props = Maps.newHashMap(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_PREVIEW));
+ DefaultAnalysisMode mode = new DefaultAnalysisMode(props);
assertThat(mode.isPreview()).isTrue();
assertThat(mode.isIncremental()).isFalse();
- assertThat(bootstrapProps.property(CoreProperties.DRY_RUN)).isEqualTo("true");
+ assertThat(props.get(CoreProperties.DRY_RUN)).isEqualTo("true");
}
@Test
public void support_incremental_mode() {
- BootstrapProperties bootstrapProps = new BootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_INCREMENTAL));
- DefaultAnalysisMode mode = new DefaultAnalysisMode(bootstrapProps);
+ Map<String, String> props = Maps.newHashMap(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_INCREMENTAL));
+ DefaultAnalysisMode mode = new DefaultAnalysisMode(props);
assertThat(mode.isPreview()).isTrue();
assertThat(mode.isIncremental()).isTrue();
- assertThat(bootstrapProps.property(CoreProperties.DRY_RUN)).isEqualTo("true");
+ assertThat(props.get(CoreProperties.DRY_RUN)).isEqualTo("true");
}
@Test
public void support_deprecated_dryrun_property() {
- BootstrapProperties bootstrapProps = new BootstrapProperties(ImmutableMap.of(CoreProperties.DRY_RUN, "true"));
- DefaultAnalysisMode mode = new DefaultAnalysisMode(bootstrapProps);
+ DefaultAnalysisMode mode = new DefaultAnalysisMode(Maps.newHashMap(ImmutableMap.of(CoreProperties.DRY_RUN, "true")));
assertThat(mode.isPreview()).isTrue();
assertThat(mode.isIncremental()).isFalse();
diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/InitialOpenIssuesStackTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/InitialOpenIssuesStackTest.java
index 34adce38fa1..a98952d5ec9 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/InitialOpenIssuesStackTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/InitialOpenIssuesStackTest.java
@@ -73,7 +73,7 @@ public class InitialOpenIssuesStackTest {
IssueDto issueDto = new IssueDto().setComponentKey("org.struts.Action").setKee("ISSUE-1");
stack.addIssue(issueDto);
- List<PreviousIssue> issueDtos = stack.selectAndRemoveIssues("org.struts.Action");
+ List<ServerIssue> issueDtos = stack.selectAndRemoveIssues("org.struts.Action");
assertThat(issueDtos).hasSize(1);
assertThat(issueDtos.get(0).key()).isEqualTo("ISSUE-1");
@@ -85,7 +85,7 @@ public class InitialOpenIssuesStackTest {
stack.addIssue(new IssueDto().setComponentKey("org.struts.Action").setKee("ISSUE-1"));
stack.addIssue(new IssueDto().setComponentKey("org.struts.Action").setKee("ISSUE-2"));
- List<PreviousIssue> issueDtos = stack.selectAndRemoveIssues("org.struts.Action");
+ List<ServerIssue> issueDtos = stack.selectAndRemoveIssues("org.struts.Action");
assertThat(issueDtos).hasSize(2);
assertThat(stack.selectAllIssues()).isEmpty();
@@ -95,7 +95,7 @@ public class InitialOpenIssuesStackTest {
public void get_and_remove_do_nothing_if_resource_not_found() {
stack.addIssue(new IssueDto().setComponentKey("org.struts.Action").setKee("ISSUE-1"));
- List<PreviousIssue> issueDtos = stack.selectAndRemoveIssues("Other");
+ List<ServerIssue> issueDtos = stack.selectAndRemoveIssues("Other");
assertThat(issueDtos).hasSize(0);
assertThat(stack.selectAllIssues()).hasSize(1);
diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueTrackingDecoratorTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueTrackingDecoratorTest.java
index 439457caa78..cd3746ef401 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueTrackingDecoratorTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueTrackingDecoratorTest.java
@@ -130,7 +130,7 @@ public class IssueTrackingDecoratorTest {
// INPUT : one issue, no open issues during previous scan, no filtering
when(issueCache.byComponent("struts:Action.java")).thenReturn(Arrays.asList(issue));
- List<PreviousIssue> dbIssues = Collections.emptyList();
+ List<ServerIssue> dbIssues = Collections.emptyList();
when(initialOpenIssues.selectAndRemoveIssues("struts:Action.java")).thenReturn(dbIssues);
when(inputPathCache.getFile("foo", "Action.java")).thenReturn(mock(DefaultInputFile.class));
when(inputPathCache.getFileMetadata("foo", "Action.java")).thenReturn(new InputFileMetadata());
@@ -155,7 +155,7 @@ public class IssueTrackingDecoratorTest {
Resource file = File.create("Action.java").setEffectiveKey("struts:Action.java").setId(123);
// INPUT : one issue existing during previous scan
- PreviousIssue unmatchedIssue = new PreviousIssueFromDb(new IssueDto().setKee("ABCDE").setResolution(null).setStatus("OPEN").setRuleKey("squid", "AvoidCycle"));
+ ServerIssue unmatchedIssue = new ServerIssueFromDb(new IssueDto().setKee("ABCDE").setResolution(null).setStatus("OPEN").setRuleKey("squid", "AvoidCycle"));
IssueTrackingResult trackingResult = new IssueTrackingResult();
trackingResult.addUnmatched(unmatchedIssue);
@@ -181,7 +181,7 @@ public class IssueTrackingDecoratorTest {
@Test
public void manual_issues_should_be_moved_if_matching_line_found() throws Exception {
// INPUT : one issue existing during previous scan
- PreviousIssue unmatchedIssue = new PreviousIssueFromDb(new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(6).setStatus("OPEN").setRuleKey("manual", "Performance"));
+ ServerIssue unmatchedIssue = new ServerIssueFromDb(new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(6).setStatus("OPEN").setRuleKey("manual", "Performance"));
when(ruleFinder.findByKey(RuleKey.of("manual", "Performance"))).thenReturn(new Rule("manual", "Performance"));
IssueTrackingResult trackingResult = new IssueTrackingResult();
@@ -240,7 +240,7 @@ public class IssueTrackingDecoratorTest {
public void manual_issues_should_be_untouched_if_already_closed() throws Exception {
// INPUT : one issue existing during previous scan
- PreviousIssue unmatchedIssue = new PreviousIssueFromDb(new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(1).setStatus("CLOSED").setRuleKey("manual", "Performance"));
+ ServerIssue unmatchedIssue = new ServerIssueFromDb(new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(1).setStatus("CLOSED").setRuleKey("manual", "Performance"));
when(ruleFinder.findByKey(RuleKey.of("manual", "Performance"))).thenReturn(new Rule("manual", "Performance"));
IssueTrackingResult trackingResult = new IssueTrackingResult();
@@ -272,7 +272,7 @@ public class IssueTrackingDecoratorTest {
public void manual_issues_should_be_untouched_if_line_is_null() throws Exception {
// INPUT : one issue existing during previous scan
- PreviousIssue unmatchedIssue = new PreviousIssueFromDb(new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(null).setStatus("OPEN").setRuleKey("manual", "Performance"));
+ ServerIssue unmatchedIssue = new ServerIssueFromDb(new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(null).setStatus("OPEN").setRuleKey("manual", "Performance"));
when(ruleFinder.findByKey(RuleKey.of("manual", "Performance"))).thenReturn(new Rule("manual", "Performance"));
IssueTrackingResult trackingResult = new IssueTrackingResult();
@@ -306,7 +306,7 @@ public class IssueTrackingDecoratorTest {
// INPUT : one issue existing during previous scan
final int issueOnLine = 6;
- PreviousIssue unmatchedIssue = new PreviousIssueFromDb(new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(issueOnLine).setStatus("OPEN")
+ ServerIssue unmatchedIssue = new ServerIssueFromDb(new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(issueOnLine).setStatus("OPEN")
.setRuleKey("manual", "Performance"));
when(ruleFinder.findByKey(RuleKey.of("manual", "Performance"))).thenReturn(new Rule("manual", "Performance"));
@@ -354,7 +354,7 @@ public class IssueTrackingDecoratorTest {
// INPUT : one issue existing during previous scan
final int issueOnLine = 3;
- PreviousIssue unmatchedIssue = new PreviousIssueFromDb(new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(issueOnLine).setStatus("OPEN")
+ ServerIssue unmatchedIssue = new ServerIssueFromDb(new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(issueOnLine).setStatus("OPEN")
.setRuleKey("manual", "Performance"));
when(ruleFinder.findByKey(RuleKey.of("manual", "Performance"))).thenReturn(new Rule("manual", "Performance"));
@@ -400,7 +400,7 @@ public class IssueTrackingDecoratorTest {
// "Unmatched" issues existed in previous scan but not in current one -> they have to be closed
// INPUT : one issue existing during previous scan
- PreviousIssue unmatchedIssue = new PreviousIssueFromDb(new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(1).setStatus("OPEN").setRuleKey("manual", "Performance"));
+ ServerIssue unmatchedIssue = new ServerIssueFromDb(new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(1).setStatus("OPEN").setRuleKey("manual", "Performance"));
when(ruleFinder.findByKey(RuleKey.of("manual", "Performance"))).thenReturn(new Rule("manual", "Performance").setStatus(Rule.STATUS_REMOVED));
IssueTrackingResult trackingResult = new IssueTrackingResult();
@@ -431,7 +431,7 @@ public class IssueTrackingDecoratorTest {
// "Unmatched" issues existed in previous scan but not in current one -> they have to be closed
// INPUT : one issue existing during previous scan
- PreviousIssue unmatchedIssue = new PreviousIssueFromDb(new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(1).setStatus("OPEN").setRuleKey("manual", "Performance"));
+ ServerIssue unmatchedIssue = new ServerIssueFromDb(new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(1).setStatus("OPEN").setRuleKey("manual", "Performance"));
when(ruleFinder.findByKey(RuleKey.of("manual", "Performance"))).thenReturn(null);
IssueTrackingResult trackingResult = new IssueTrackingResult();
@@ -462,7 +462,7 @@ public class IssueTrackingDecoratorTest {
// "Unmatched" issues existed in previous scan but not in current one -> they have to be closed
// INPUT : one issue existing during previous scan
- PreviousIssue unmatchedIssue = new PreviousIssueFromDb(new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(6).setStatus("OPEN").setRuleKey("manual", "Performance"));
+ ServerIssue unmatchedIssue = new ServerIssueFromDb(new IssueDto().setKee("ABCDE").setReporter("freddy").setLine(6).setStatus("OPEN").setRuleKey("manual", "Performance"));
when(ruleFinder.findByKey(RuleKey.of("manual", "Performance"))).thenReturn(null);
IssueTrackingResult trackingResult = new IssueTrackingResult();
@@ -527,7 +527,7 @@ public class IssueTrackingDecoratorTest {
@Test
public void merge_matched_issue() throws Exception {
- PreviousIssue previousIssue = new PreviousIssueFromDb(new IssueDto().setKee("ABCDE").setResolution(null).setStatus("OPEN").setRuleKey("squid", "AvoidCycle")
+ ServerIssue previousIssue = new ServerIssueFromDb(new IssueDto().setKee("ABCDE").setResolution(null).setStatus("OPEN").setRuleKey("squid", "AvoidCycle")
.setLine(10).setSeverity("MAJOR").setMessage("Message").setEffortToFix(1.5).setDebt(1L).setProjectKey("sample"));
DefaultIssue issue = new DefaultIssue();
@@ -546,7 +546,7 @@ public class IssueTrackingDecoratorTest {
@Test
public void merge_matched_issue_on_manual_severity() throws Exception {
- PreviousIssue previousIssue = new PreviousIssueFromDb(new IssueDto().setKee("ABCDE").setResolution(null).setStatus("OPEN").setRuleKey("squid", "AvoidCycle")
+ ServerIssue previousIssue = new ServerIssueFromDb(new IssueDto().setKee("ABCDE").setResolution(null).setStatus("OPEN").setRuleKey("squid", "AvoidCycle")
.setLine(10).setManualSeverity(true).setSeverity("MAJOR").setMessage("Message").setEffortToFix(1.5).setDebt(1L));
DefaultIssue issue = new DefaultIssue();
@@ -564,7 +564,7 @@ public class IssueTrackingDecoratorTest {
public void merge_issue_changelog_with_previous_changelog() throws Exception {
when(initialOpenIssues.selectChangelog("ABCDE")).thenReturn(newArrayList(new IssueChangeDto().setIssueKey("ABCD").setCreatedAt(System2.INSTANCE.now())));
- PreviousIssue previousIssue = new PreviousIssueFromDb(new IssueDto().setKee("ABCDE").setResolution(null).setStatus("OPEN").setRuleKey("squid", "AvoidCycle")
+ ServerIssue previousIssue = new ServerIssueFromDb(new IssueDto().setKee("ABCDE").setResolution(null).setStatus("OPEN").setRuleKey("squid", "AvoidCycle")
.setLine(10).setMessage("Message").setEffortToFix(1.5).setDebt(1L).setCreatedAt(System2.INSTANCE.now()));
DefaultIssue issue = new DefaultIssue();
diff --git a/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueTrackingTest.java b/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueTrackingTest.java
index 095429f3cbf..a58f1bb7068 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueTrackingTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/issue/tracking/IssueTrackingTest.java
@@ -71,24 +71,24 @@ public class IssueTrackingTest {
@Test
public void key_should_be_the_prioritary_field_to_check() {
- PreviousIssueFromDb referenceIssue1 = newReferenceIssue("message", 10, "squid", "AvoidCycle", "checksum1");
+ ServerIssueFromDb referenceIssue1 = newReferenceIssue("message", 10, "squid", "AvoidCycle", "checksum1");
referenceIssue1.getDto().setKee("100");
- PreviousIssueFromDb referenceIssue2 = newReferenceIssue("message", 10, "squid", "AvoidCycle", "checksum2");
+ ServerIssueFromDb referenceIssue2 = newReferenceIssue("message", 10, "squid", "AvoidCycle", "checksum2");
referenceIssue2.getDto().setKee("200");
// exactly the fields of referenceIssue1 but not the same key
DefaultIssue newIssue = newDefaultIssue("message", 10, RuleKey.of("squid", "AvoidCycle"), "checksum1").setKey("200");
IssueTrackingResult result = new IssueTrackingResult();
- tracking.mapIssues(newArrayList(newIssue), Lists.<PreviousIssue>newArrayList(referenceIssue1, referenceIssue2), null, result);
+ tracking.mapIssues(newArrayList(newIssue), Lists.<ServerIssue>newArrayList(referenceIssue1, referenceIssue2), null, result);
// same key
assertThat(result.matching(newIssue)).isSameAs(referenceIssue2);
}
@Test
public void checksum_should_have_greater_priority_than_line() {
- PreviousIssue referenceIssue1 = newReferenceIssue("message", 1, "squid", "AvoidCycle", "checksum1");
- PreviousIssue referenceIssue2 = newReferenceIssue("message", 3, "squid", "AvoidCycle", "checksum2");
+ ServerIssue referenceIssue1 = newReferenceIssue("message", 1, "squid", "AvoidCycle", "checksum1");
+ ServerIssue referenceIssue2 = newReferenceIssue("message", 3, "squid", "AvoidCycle", "checksum2");
DefaultIssue newIssue1 = newDefaultIssue("message", 3, RuleKey.of("squid", "AvoidCycle"), "checksum1");
DefaultIssue newIssue2 = newDefaultIssue("message", 5, RuleKey.of("squid", "AvoidCycle"), "checksum2");
@@ -105,7 +105,7 @@ public class IssueTrackingTest {
@Test
public void same_rule_and_null_line_and_checksum_but_different_messages() {
DefaultIssue newIssue = newDefaultIssue("new message", null, RuleKey.of("squid", "AvoidCycle"), "checksum1");
- PreviousIssue referenceIssue = newReferenceIssue("old message", null, "squid", "AvoidCycle", "checksum1");
+ ServerIssue referenceIssue = newReferenceIssue("old message", null, "squid", "AvoidCycle", "checksum1");
IssueTrackingResult result = new IssueTrackingResult();
tracking.mapIssues(newArrayList(newIssue), newArrayList(referenceIssue), null, result);
@@ -115,7 +115,7 @@ public class IssueTrackingTest {
@Test
public void same_rule_and_line_and_checksum_but_different_messages() {
DefaultIssue newIssue = newDefaultIssue("new message", 1, RuleKey.of("squid", "AvoidCycle"), "checksum1");
- PreviousIssue referenceIssue = newReferenceIssue("old message", 1, "squid", "AvoidCycle", "checksum1");
+ ServerIssue referenceIssue = newReferenceIssue("old message", 1, "squid", "AvoidCycle", "checksum1");
IssueTrackingResult result = new IssueTrackingResult();
tracking.mapIssues(newArrayList(newIssue), newArrayList(referenceIssue), null, result);
@@ -125,7 +125,7 @@ public class IssueTrackingTest {
@Test
public void same_rule_and_line_message() {
DefaultIssue newIssue = newDefaultIssue("message", 1, RuleKey.of("squid", "AvoidCycle"), "checksum1");
- PreviousIssue referenceIssue = newReferenceIssue("message", 1, "squid", "AvoidCycle", "checksum2");
+ ServerIssue referenceIssue = newReferenceIssue("message", 1, "squid", "AvoidCycle", "checksum2");
IssueTrackingResult result = new IssueTrackingResult();
tracking.mapIssues(newArrayList(newIssue), newArrayList(referenceIssue), null, result);
@@ -135,7 +135,7 @@ public class IssueTrackingTest {
@Test
public void should_ignore_reference_measure_without_checksum() {
DefaultIssue newIssue = newDefaultIssue("message", 1, RuleKey.of("squid", "AvoidCycle"), null);
- PreviousIssue referenceIssue = newReferenceIssue("message", 1, "squid", "NullDeref", null);
+ ServerIssue referenceIssue = newReferenceIssue("message", 1, "squid", "NullDeref", null);
IssueTrackingResult result = new IssueTrackingResult();
tracking.mapIssues(newArrayList(newIssue), newArrayList(referenceIssue), null, result);
@@ -145,7 +145,7 @@ public class IssueTrackingTest {
@Test
public void same_rule_and_message_and_checksum_but_different_line() {
DefaultIssue newIssue = newDefaultIssue("message", 1, RuleKey.of("squid", "AvoidCycle"), "checksum1");
- PreviousIssue referenceIssue = newReferenceIssue("message", 2, "squid", "AvoidCycle", "checksum1");
+ ServerIssue referenceIssue = newReferenceIssue("message", 2, "squid", "AvoidCycle", "checksum1");
IssueTrackingResult result = new IssueTrackingResult();
tracking.mapIssues(newArrayList(newIssue), newArrayList(referenceIssue), null, result);
@@ -158,7 +158,7 @@ public class IssueTrackingTest {
@Test
public void same_checksum_and_rule_but_different_line_and_different_message() {
DefaultIssue newIssue = newDefaultIssue("new message", 1, RuleKey.of("squid", "AvoidCycle"), "checksum1");
- PreviousIssue referenceIssue = newReferenceIssue("old message", 2, "squid", "AvoidCycle", "checksum1");
+ ServerIssue referenceIssue = newReferenceIssue("old message", 2, "squid", "AvoidCycle", "checksum1");
IssueTrackingResult result = new IssueTrackingResult();
tracking.mapIssues(newArrayList(newIssue), newArrayList(referenceIssue), null, result);
@@ -168,7 +168,7 @@ public class IssueTrackingTest {
@Test
public void should_create_new_issue_when_same_rule_same_message_but_different_line_and_checksum() {
DefaultIssue newIssue = newDefaultIssue("message", 1, RuleKey.of("squid", "AvoidCycle"), "checksum1");
- PreviousIssue referenceIssue = newReferenceIssue("message", 2, "squid", "AvoidCycle", "checksum2");
+ ServerIssue referenceIssue = newReferenceIssue("message", 2, "squid", "AvoidCycle", "checksum2");
IssueTrackingResult result = new IssueTrackingResult();
tracking.mapIssues(newArrayList(newIssue), newArrayList(referenceIssue), null, result);
@@ -178,7 +178,7 @@ public class IssueTrackingTest {
@Test
public void should_not_track_issue_if_different_rule() {
DefaultIssue newIssue = newDefaultIssue("message", 1, RuleKey.of("squid", "AvoidCycle"), "checksum1");
- PreviousIssue referenceIssue = newReferenceIssue("message", 1, "squid", "NullDeref", "checksum1");
+ ServerIssue referenceIssue = newReferenceIssue("message", 1, "squid", "NullDeref", "checksum1");
IssueTrackingResult result = new IssueTrackingResult();
tracking.mapIssues(newArrayList(newIssue), newArrayList(referenceIssue), null, result);
@@ -190,7 +190,7 @@ public class IssueTrackingTest {
// issue messages are trimmed and can be abbreviated when persisted in database.
// Comparing issue messages must use the same format.
DefaultIssue newIssue = newDefaultIssue(" message ", 1, RuleKey.of("squid", "AvoidCycle"), "checksum1");
- PreviousIssue referenceIssue = newReferenceIssue("message", 1, "squid", "AvoidCycle", "checksum2");
+ ServerIssue referenceIssue = newReferenceIssue("message", 1, "squid", "AvoidCycle", "checksum2");
IssueTrackingResult result = new IssueTrackingResult();
tracking.mapIssues(newArrayList(newIssue), newArrayList(referenceIssue), null, result);
@@ -202,7 +202,7 @@ public class IssueTrackingTest {
initLastHashes("example2-v1", "example2-v2");
DefaultIssue newIssue = newDefaultIssue("Indentation", 9, RuleKey.of("squid", "AvoidCycle"), "foo");
- PreviousIssue referenceIssue = newReferenceIssue("2 branches need to be covered", null, "squid", "AvoidCycle", null);
+ ServerIssue referenceIssue = newReferenceIssue("2 branches need to be covered", null, "squid", "AvoidCycle", null);
IssueTrackingResult result = tracking.track(sourceHashHolder, newArrayList(referenceIssue), newArrayList(newIssue));
@@ -214,7 +214,7 @@ public class IssueTrackingTest {
initLastHashes("example2-v1", "example2-v2");
DefaultIssue newIssue = newDefaultIssue("1 branch need to be covered", null, RuleKey.of("squid", "AvoidCycle"), "foo");
- PreviousIssue referenceIssue = newReferenceIssue("Indentationd", 7, "squid", "AvoidCycle", null);
+ ServerIssue referenceIssue = newReferenceIssue("Indentationd", 7, "squid", "AvoidCycle", null);
IssueTrackingResult result = tracking.track(sourceHashHolder, newArrayList(referenceIssue), newArrayList(newIssue));
@@ -229,7 +229,7 @@ public class IssueTrackingTest {
initLastHashes("example2-v1", "example2-v2");
DefaultIssue newIssue = newDefaultIssue("1 branch need to be covered", null, RuleKey.of("squid", "AvoidCycle"), null);
- PreviousIssue referenceIssue = newReferenceIssue("2 branches need to be covered", null, "squid", "AvoidCycle", null);
+ ServerIssue referenceIssue = newReferenceIssue("2 branches need to be covered", null, "squid", "AvoidCycle", null);
IssueTrackingResult result = tracking.track(sourceHashHolder, newArrayList(referenceIssue), newArrayList(newIssue));
@@ -243,8 +243,8 @@ public class IssueTrackingTest {
public void should_track_issues_based_on_blocks_recognition_on_example1() throws Exception {
initLastHashes("example1-v1", "example1-v2");
- PreviousIssue referenceIssue1 = newReferenceIssue("Indentation", 7, "squid", "AvoidCycle", null);
- PreviousIssue referenceIssue2 = newReferenceIssue("Indentation", 11, "squid", "AvoidCycle", null);
+ ServerIssue referenceIssue1 = newReferenceIssue("Indentation", 7, "squid", "AvoidCycle", null);
+ ServerIssue referenceIssue2 = newReferenceIssue("Indentation", 11, "squid", "AvoidCycle", null);
DefaultIssue newIssue1 = newDefaultIssue("Indentation", 9, RuleKey.of("squid", "AvoidCycle"), null);
DefaultIssue newIssue2 = newDefaultIssue("Indentation", 13, RuleKey.of("squid", "AvoidCycle"), null);
@@ -266,7 +266,7 @@ public class IssueTrackingTest {
public void should_track_issues_based_on_blocks_recognition_on_example2() throws Exception {
initLastHashes("example2-v1", "example2-v2");
- PreviousIssue referenceIssue1 = newReferenceIssue("SystemPrintln", 5, "squid", "AvoidCycle", null);
+ ServerIssue referenceIssue1 = newReferenceIssue("SystemPrintln", 5, "squid", "AvoidCycle", null);
DefaultIssue newIssue1 = newDefaultIssue("SystemPrintln", 6, RuleKey.of("squid", "AvoidCycle"), null);
DefaultIssue newIssue2 = newDefaultIssue("SystemPrintln", 10, RuleKey.of("squid", "AvoidCycle"), null);
@@ -287,9 +287,9 @@ public class IssueTrackingTest {
public void should_track_issues_based_on_blocks_recognition_on_example3() throws Exception {
initLastHashes("example3-v1", "example3-v2");
- PreviousIssue referenceIssue1 = newReferenceIssue("Avoid unused local variables such as 'j'.", 6, "squid", "AvoidCycle", "63c11570fc0a76434156be5f8138fa03");
- PreviousIssue referenceIssue2 = newReferenceIssue("Avoid unused private methods such as 'myMethod()'.", 13, "squid", "NullDeref", "ef23288705d1ef1e512448ace287586e");
- PreviousIssue referenceIssue3 = newReferenceIssue("Method 'avoidUtilityClass' is not designed for extension - needs to be abstract, final or empty.", 9, "pmd",
+ ServerIssue referenceIssue1 = newReferenceIssue("Avoid unused local variables such as 'j'.", 6, "squid", "AvoidCycle", "63c11570fc0a76434156be5f8138fa03");
+ ServerIssue referenceIssue2 = newReferenceIssue("Avoid unused private methods such as 'myMethod()'.", 13, "squid", "NullDeref", "ef23288705d1ef1e512448ace287586e");
+ ServerIssue referenceIssue3 = newReferenceIssue("Method 'avoidUtilityClass' is not designed for extension - needs to be abstract, final or empty.", 9, "pmd",
"UnusedLocalVariable", "ed5cdd046fda82727d6fedd1d8e3a310");
// New issue
@@ -322,7 +322,7 @@ public class IssueTrackingTest {
public void dont_load_checksum_if_no_new_issue() throws Exception {
sourceHashHolder = mock(SourceHashHolder.class);
- PreviousIssue referenceIssue = newReferenceIssue("2 branches need to be covered", null, "squid", "AvoidCycle", null);
+ ServerIssue referenceIssue = newReferenceIssue("2 branches need to be covered", null, "squid", "AvoidCycle", null);
tracking.track(sourceHashHolder, newArrayList(referenceIssue), Collections.<DefaultIssue>emptyList());
@@ -337,7 +337,7 @@ public class IssueTrackingTest {
return new DefaultIssue().setMessage(message).setLine(line).setRuleKey(ruleKey).setChecksum(checksum).setStatus(Issue.STATUS_OPEN);
}
- private PreviousIssueFromDb newReferenceIssue(String message, Integer lineId, String ruleRepo, String ruleKey, String lineChecksum) {
+ private ServerIssueFromDb newReferenceIssue(String message, Integer lineId, String ruleRepo, String ruleKey, String lineChecksum) {
IssueDto referenceIssue = new IssueDto();
Long id = violationId++;
referenceIssue.setId(id);
@@ -348,7 +348,7 @@ public class IssueTrackingTest {
referenceIssue.setChecksum(lineChecksum);
referenceIssue.setResolution(null);
referenceIssue.setStatus(Issue.STATUS_OPEN);
- return new PreviousIssueFromDb(referenceIssue);
+ return new ServerIssueFromDb(referenceIssue);
}
private void initLastHashes(String reference, String newSource) throws IOException {
diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/IncrementalModeMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/IncrementalModeMediumTest.java
new file mode 100644
index 00000000000..f1b91f30b68
--- /dev/null
+++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/preview/IncrementalModeMediumTest.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.mediumtest.preview;
+
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.io.FileUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.issue.Issue;
+import org.sonar.batch.mediumtest.BatchMediumTester;
+import org.sonar.batch.mediumtest.TaskResult;
+import org.sonar.batch.protocol.Constants.Severity;
+import org.sonar.batch.protocol.input.ActiveRule;
+import org.sonar.batch.protocol.input.FileData;
+import org.sonar.xoo.XooPlugin;
+
+import java.io.File;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class IncrementalModeMediumTest {
+
+ private static final String SAMPLE_CONTENT = "Sample content\nwith\n4\nlines";
+
+ @org.junit.Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ private static SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
+
+ private static Long date(String date) {
+ try {
+ return sdf.parse(date).getTime();
+ } catch (ParseException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ public BatchMediumTester tester = BatchMediumTester.builder()
+ .bootstrapProperties(ImmutableMap.of(CoreProperties.ANALYSIS_MODE, CoreProperties.ANALYSIS_MODE_INCREMENTAL))
+ .registerPlugin("xoo", new XooPlugin())
+ .addDefaultQProfile("xoo", "Sonar Way")
+ .activateRule(new ActiveRule("xoo", "OneIssuePerLine", null, "One issue per line", "MAJOR", null, "xoo"))
+ .activateRule(new ActiveRule("manual", "MyManualIssue", null, "My manual issue", "MAJOR", null, null))
+ .setPreviousAnalysisDate(new Date())
+ .addFileData("sample", "xources/hello/HelloJava.xoo", new FileData(DigestUtils.md5Hex(SAMPLE_CONTENT), false, null, null, null))
+ // Existing issue
+ .mockServerIssue(org.sonar.batch.protocol.input.BatchInput.ServerIssue.newBuilder().setKey("xyz")
+ .setModuleKey("sample")
+ .setPath("src/sample.xoo")
+ .setRuleRepository("xoo")
+ .setRuleKey("OneIssuePerLine")
+ .setLine(1)
+ .setSeverity(Severity.MAJOR)
+ .setCreationDate(date("14/03/2004"))
+ .setChecksum(DigestUtils.md5Hex("Samplecontent"))
+ .setStatus("OPEN")
+ .build())
+ // Resolved issue
+ .mockServerIssue(org.sonar.batch.protocol.input.BatchInput.ServerIssue.newBuilder().setKey("resolved")
+ .setModuleKey("sample")
+ .setPath("src/sample.xoo")
+ .setRuleRepository("xoo")
+ .setRuleKey("OneIssuePerLine")
+ .setLine(1)
+ .setSeverity(Severity.MAJOR)
+ .setCreationDate(date("14/03/2004"))
+ .setChecksum(DigestUtils.md5Hex("dontexist"))
+ .setStatus("OPEN")
+ .build())
+ // Manual issue
+ .mockServerIssue(org.sonar.batch.protocol.input.BatchInput.ServerIssue.newBuilder().setKey("manual")
+ .setModuleKey("sample")
+ .setPath("src/sample.xoo")
+ .setRuleRepository("manual")
+ .setRuleKey("MyManualIssue")
+ .setLine(1)
+ .setSeverity(Severity.MAJOR)
+ .setCreationDate(date("14/03/2004"))
+ .setChecksum(DigestUtils.md5Hex("Samplecontent"))
+ .setStatus("OPEN")
+ .build())
+ .build();
+
+ @Before
+ public void prepare() {
+ tester.start();
+ }
+
+ @After
+ public void stop() {
+ tester.stop();
+ }
+
+ @Test
+ public void testIssueTrackingIncrementalMode() throws Exception {
+ File baseDir = temp.newFolder();
+ File srcDir = new File(baseDir, "src");
+ srcDir.mkdir();
+
+ File xooFile = new File(srcDir, "sample.xoo");
+ FileUtils.write(xooFile, SAMPLE_CONTENT);
+
+ TaskResult result = tester.newTask()
+ .properties(ImmutableMap.<String, String>builder()
+ .put("sonar.task", "scan")
+ .put("sonar.projectBaseDir", baseDir.getAbsolutePath())
+ .put("sonar.projectKey", "sample")
+ .put("sonar.projectName", "Foo Project")
+ .put("sonar.projectVersion", "1.0-SNAPSHOT")
+ .put("sonar.projectDescription", "Description of Foo Project")
+ .put("sonar.sources", "src")
+ .build())
+ .start();
+
+ int newIssues = 0;
+ int openIssues = 0;
+ int resolvedIssue = 0;
+ for (Issue issue : result.issues()) {
+ if (issue.isNew()) {
+ newIssues++;
+ } else if (issue.resolution() != null) {
+ resolvedIssue++;
+ } else {
+ openIssues++;
+ }
+ }
+ assertThat(newIssues).isEqualTo(3);
+ assertThat(openIssues).isEqualTo(2);
+ assertThat(resolvedIssue).isEqualTo(1);
+ }
+
+}
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 6cb9e22fb00..c8368f37246 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
@@ -21,16 +21,20 @@ package org.sonar.batch.mediumtest.preview;
import com.google.common.collect.ImmutableMap;
import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.io.FileUtils;
import org.junit.After;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.CoreProperties;
import org.sonar.api.issue.Issue;
+import org.sonar.api.utils.log.LogTester;
import org.sonar.batch.mediumtest.BatchMediumTester;
import org.sonar.batch.mediumtest.TaskResult;
+import org.sonar.batch.protocol.Constants.Severity;
import org.sonar.batch.protocol.input.ActiveRule;
-import org.sonar.batch.protocol.input.issues.PreviousIssue;
+import org.sonar.batch.scan.report.ConsoleReport;
import org.sonar.xoo.XooPlugin;
import java.io.File;
@@ -42,14 +46,17 @@ import static org.assertj.core.api.Assertions.assertThat;
public class PreviewAndReportsMediumTest {
- @org.junit.Rule
+ @Rule
public TemporaryFolder temp = new TemporaryFolder();
+ @Rule
+ public LogTester logTester = new LogTester();
+
private static SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
- private static Date date(String date) {
+ private static Long date(String date) {
try {
- return sdf.parse(date);
+ return sdf.parse(date).getTime();
} catch (ParseException e) {
throw new IllegalStateException(e);
}
@@ -62,33 +69,51 @@ public class PreviewAndReportsMediumTest {
.activateRule(new ActiveRule("xoo", "OneIssuePerLine", null, "One issue per line", "MAJOR", null, "xoo"))
.activateRule(new ActiveRule("manual", "MyManualIssue", null, "My manual issue", "MAJOR", null, null))
.setPreviousAnalysisDate(new Date())
- // Existing issue
- .addPreviousIssue(new PreviousIssue().setKey("xyz")
- .setComponentKey("sample:xources/hello/HelloJava.xoo")
- .setRuleKey("xoo", "OneIssuePerLine")
+ // Existing issue that is still detected
+ .mockServerIssue(org.sonar.batch.protocol.input.BatchInput.ServerIssue.newBuilder().setKey("xyz")
+ .setModuleKey("sample")
+ .setPath("xources/hello/HelloJava.xoo")
+ .setRuleRepository("xoo")
+ .setRuleKey("OneIssuePerLine")
.setLine(1)
- .setSeverity("MAJOR")
+ .setSeverity(Severity.MAJOR)
.setCreationDate(date("14/03/2004"))
.setChecksum(DigestUtils.md5Hex("packagehello;"))
- .setStatus("OPEN"))
- // Resolved issue
- .addPreviousIssue(new PreviousIssue().setKey("resolved")
- .setComponentKey("sample:xources/hello/HelloJava.xoo")
- .setRuleKey("xoo", "OneIssuePerLine")
+ .setStatus("OPEN")
+ .build())
+ // Existing issue that is no more detected (will be closed)
+ .mockServerIssue(org.sonar.batch.protocol.input.BatchInput.ServerIssue.newBuilder().setKey("resolved")
+ .setModuleKey("sample")
+ .setPath("xources/hello/HelloJava.xoo")
+ .setRuleRepository("xoo")
+ .setRuleKey("OneIssuePerLine")
.setLine(1)
- .setSeverity("MAJOR")
+ .setSeverity(Severity.MAJOR)
.setCreationDate(date("14/03/2004"))
.setChecksum(DigestUtils.md5Hex("dontexist"))
- .setStatus("OPEN"))
+ .setStatus("OPEN")
+ .build())
+ // Existing issue on project that is no more detected
+ .mockServerIssue(org.sonar.batch.protocol.input.BatchInput.ServerIssue.newBuilder().setKey("resolved-on-project")
+ .setModuleKey("sample")
+ .setRuleRepository("xoo")
+ .setRuleKey("OneIssuePerModule")
+ .setSeverity(Severity.CRITICAL)
+ .setCreationDate(date("14/03/2004"))
+ .setStatus("OPEN")
+ .build())
// Manual issue
- .addPreviousIssue(new PreviousIssue().setKey("manual")
- .setComponentKey("sample:xources/hello/HelloJava.xoo")
- .setRuleKey("manual", "MyManualIssue")
+ .mockServerIssue(org.sonar.batch.protocol.input.BatchInput.ServerIssue.newBuilder().setKey("manual")
+ .setModuleKey("sample")
+ .setPath("xources/hello/HelloJava.xoo")
+ .setRuleRepository("manual")
+ .setRuleKey("MyManualIssue")
.setLine(1)
- .setSeverity("MAJOR")
+ .setSeverity(Severity.MAJOR)
.setCreationDate(date("14/03/2004"))
.setChecksum(DigestUtils.md5Hex("packagehello;"))
- .setStatus("OPEN"))
+ .setStatus("OPEN")
+ .build())
.build();
@Before
@@ -123,26 +148,35 @@ public class PreviewAndReportsMediumTest {
}
assertThat(newIssues).isEqualTo(13);
assertThat(openIssues).isEqualTo(2);
- assertThat(resolvedIssue).isEqualTo(1);
+ assertThat(resolvedIssue).isEqualTo(2);
}
@Test
public void testConsoleReport() throws Exception {
File projectDir = new File(PreviewAndReportsMediumTest.class.getResource("/mediumtest/xoo/sample").toURI());
- TaskResult result = tester
+ tester
.newScanTask(new File(projectDir, "sonar-project.properties"))
.property("sonar.issuesReport.console.enable", "true")
.start();
- // TODO wait for ability to assert on logs
+ assertThat(getReportLog()).contains("+13 issues", "+13 major");
+ }
+
+ private String getReportLog() {
+ for (String log : logTester.logs()) {
+ if (log.contains(ConsoleReport.HEADER)) {
+ return log;
+ }
+ }
+ throw new IllegalStateException("No console report");
}
@Test
public void testHtmlReport() throws Exception {
File projectDir = new File(PreviewAndReportsMediumTest.class.getResource("/mediumtest/xoo/sample").toURI());
- TaskResult result = tester
+ tester
.newScanTask(new File(projectDir, "sonar-project.properties"))
.property("sonar.issuesReport.html.enable", "true")
.start();
@@ -151,4 +185,27 @@ public class PreviewAndReportsMediumTest {
assertThat(new File(projectDir, ".sonar/issues-report/issues-report-light.html")).exists();
}
+ @Test
+ public void testHtmlReportNoFile() throws Exception {
+ File baseDir = temp.newFolder();
+ File srcDir = new File(baseDir, "src");
+ srcDir.mkdir();
+
+ tester.newTask()
+ .properties(ImmutableMap.<String, String>builder()
+ .put("sonar.task", "scan")
+ .put("sonar.projectBaseDir", baseDir.getAbsolutePath())
+ .put("sonar.projectKey", "sample")
+ .put("sonar.projectName", "Foo Project")
+ .put("sonar.projectVersion", "1.0-SNAPSHOT")
+ .put("sonar.projectDescription", "Description of Foo Project")
+ .put("sonar.sources", "src")
+ .put("sonar.issuesReport.html.enable", "true")
+ .build())
+ .start();
+
+ assertThat(FileUtils.readFileToString(new File(baseDir, ".sonar/issues-report/issues-report.html"))).contains("No file analyzed");
+ assertThat(FileUtils.readFileToString(new File(baseDir, ".sonar/issues-report/issues-report-light.html"))).contains("No file analyzed");
+ }
+
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectScanContainerTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectScanContainerTest.java
index d80410825e3..5c98be19187 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectScanContainerTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/scan/ProjectScanContainerTest.java
@@ -62,7 +62,7 @@ public class ProjectScanContainerTest {
public void prepare() {
projectBootstrapper = mock(ProjectBootstrapper.class);
bootstrapProperties = new BootstrapProperties(Collections.<String, String>emptyMap());
- DefaultAnalysisMode analysisMode = new DefaultAnalysisMode(bootstrapProperties);
+ DefaultAnalysisMode analysisMode = new DefaultAnalysisMode(Collections.<String, String>emptyMap());
when(projectBootstrapper.bootstrap()).thenReturn(new ProjectReactor(ProjectDefinition.create()));
parentContainer = new ComponentContainer();
parentContainer.add(System2.INSTANCE);
diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/report/ConsoleReportTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/report/ConsoleReportTest.java
new file mode 100644
index 00000000000..6bbc93aba52
--- /dev/null
+++ b/sonar-batch/src/test/java/org/sonar/batch/scan/report/ConsoleReportTest.java
@@ -0,0 +1,134 @@
+/*
+ * 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.scan.report;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.config.Settings;
+import org.sonar.api.issue.internal.DefaultIssue;
+import org.sonar.api.rule.Severity;
+import org.sonar.api.utils.log.LogTester;
+import org.sonar.batch.issue.IssueCache;
+import org.sonar.batch.scan.filesystem.InputPathCache;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class ConsoleReportTest {
+
+ @Rule
+ public LogTester logTester = new LogTester();
+
+ private Settings settings;
+ private IssueCache issueCache;
+ private InputPathCache inputPathCache;
+ private ConsoleReport report;
+
+ @Before
+ public void prepare() {
+ settings = new Settings();
+ issueCache = mock(IssueCache.class);
+ inputPathCache = mock(InputPathCache.class);
+ report = new ConsoleReport(settings, issueCache, inputPathCache);
+ }
+
+ @Test
+ public void dontExecuteByDefault() {
+ report.execute();
+ for (String log : logTester.logs()) {
+ assertThat(log).doesNotContain(ConsoleReport.HEADER);
+ }
+ }
+
+ @Test
+ public void testNoFile() {
+ settings.setProperty(ConsoleReport.CONSOLE_REPORT_ENABLED_KEY, "true");
+ when(inputPathCache.allFiles()).thenReturn(Collections.<InputFile>emptyList());
+ when(issueCache.all()).thenReturn(Collections.<DefaultIssue>emptyList());
+ report.execute();
+ assertThat(getReportLog()).isEqualTo(
+ "\n\n------------- Issues Report -------------\n\n" +
+ " No file analyzed\n" +
+ "\n-------------------------------------------\n\n");
+ }
+
+ @Test
+ public void testNoNewIssue() {
+ settings.setProperty(ConsoleReport.CONSOLE_REPORT_ENABLED_KEY, "true");
+ when(inputPathCache.allFiles()).thenReturn(Arrays.<InputFile>asList(new DefaultInputFile("foo", "src/Foo.php")));
+ when(issueCache.all()).thenReturn(Arrays.asList(new DefaultIssue().setNew(false)));
+ report.execute();
+ assertThat(getReportLog()).isEqualTo(
+ "\n\n------------- Issues Report -------------\n\n" +
+ " No new issue\n" +
+ "\n-------------------------------------------\n\n");
+ }
+
+ @Test
+ public void testOneNewIssue() {
+ settings.setProperty(ConsoleReport.CONSOLE_REPORT_ENABLED_KEY, "true");
+ when(inputPathCache.allFiles()).thenReturn(Arrays.<InputFile>asList(new DefaultInputFile("foo", "src/Foo.php")));
+ when(issueCache.all()).thenReturn(Arrays.asList(new DefaultIssue().setNew(true).setSeverity(Severity.BLOCKER)));
+ report.execute();
+ assertThat(getReportLog()).isEqualTo(
+ "\n\n------------- Issues Report -------------\n\n" +
+ " +1 issue\n\n" +
+ " +1 blocking\n" +
+ "\n-------------------------------------------\n\n");
+ }
+
+ @Test
+ public void testOneNewIssuePerSeverity() {
+ settings.setProperty(ConsoleReport.CONSOLE_REPORT_ENABLED_KEY, "true");
+ when(inputPathCache.allFiles()).thenReturn(Arrays.<InputFile>asList(new DefaultInputFile("foo", "src/Foo.php")));
+ when(issueCache.all()).thenReturn(Arrays.asList(new DefaultIssue().setNew(true).setSeverity(Severity.BLOCKER),
+ new DefaultIssue().setNew(true).setSeverity(Severity.CRITICAL),
+ new DefaultIssue().setNew(true).setSeverity(Severity.MAJOR),
+ new DefaultIssue().setNew(true).setSeverity(Severity.MINOR),
+ new DefaultIssue().setNew(true).setSeverity(Severity.INFO)));
+ report.execute();
+ assertThat(getReportLog()).isEqualTo(
+ "\n\n------------- Issues Report -------------\n\n" +
+ " +5 issues\n\n" +
+ " +1 blocking\n" +
+ " +1 critical\n" +
+ " +1 major\n" +
+ " +1 minor\n" +
+ " +1 info\n" +
+ "\n-------------------------------------------\n\n");
+ }
+
+ private String getReportLog() {
+ for (String log : logTester.logs()) {
+ if (log.contains(ConsoleReport.HEADER)) {
+ return log;
+ }
+ }
+ throw new IllegalStateException("No console report");
+ }
+
+}