@@ -90,7 +90,7 @@ public interface AnalysisMetadataHolder { | |||
boolean isCrossProjectDuplicationEnabled(); | |||
/** | |||
* Branch being analyzed. Can be of any type: long or short, main or not. | |||
* Branch being analyzed. | |||
* | |||
* @throws IllegalStateException if branch has not been set | |||
*/ |
@@ -36,11 +36,11 @@ public interface Branch extends ComponentKeyGenerator { | |||
String getName(); | |||
/** | |||
* Indicates the first LLB branch from which it was forked. | |||
* Indicates the UUID of the branch used as reference | |||
* | |||
* @throws IllegalStateException for main branches or legacy branches. | |||
*/ | |||
String getMergeBranchUuid(); | |||
String getReferenceBranchUuid(); | |||
/** | |||
* Whether the cross-project duplication tracker can be enabled |
@@ -52,7 +52,7 @@ public class BranchLoader { | |||
private static boolean hasBranchProperties(ScannerReport.Metadata metadata) { | |||
return !metadata.getBranchName().isEmpty() | |||
|| !metadata.getPullRequestKey().isEmpty() | |||
|| !metadata.getMergeBranchName().isEmpty() | |||
|| !metadata.getReferenceBranchName().isEmpty() | |||
|| metadata.getBranchType() != UNSET; | |||
} | |||
@@ -87,7 +87,7 @@ public class BranchPersisterImpl implements BranchPersister { | |||
// merge branch is only present if it's not a main branch and not an application | |||
if (!branch.isMain() && !Qualifiers.APP.equals(componentDto.qualifier())) { | |||
dto.setMergeBranchUuid(branch.getMergeBranchUuid()); | |||
dto.setMergeBranchUuid(branch.getReferenceBranchUuid()); | |||
} | |||
if (branch.getType() == BranchType.PULL_REQUEST) { |
@@ -50,7 +50,7 @@ public class DefaultBranchImpl implements Branch { | |||
} | |||
@Override | |||
public String getMergeBranchUuid() { | |||
public String getReferenceBranchUuid() { | |||
throw new IllegalStateException("Not valid for the main branch"); | |||
} | |||
@@ -1,136 +0,0 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2019 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program 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. | |||
* | |||
* This program 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.ce.task.projectanalysis.component; | |||
import java.util.HashMap; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.Optional; | |||
import javax.annotation.CheckForNull; | |||
import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.component.BranchDto; | |||
import org.sonar.db.component.ComponentDto; | |||
import static com.google.common.base.Preconditions.checkState; | |||
import static org.sonar.db.component.ComponentDto.removeBranchAndPullRequestFromKey; | |||
/** | |||
* Cache a map between component keys and uuids in the merge branch and optionally the target branch (for PRs, and only if this target branch is analyzed) | |||
*/ | |||
public class MergeAndTargetBranchComponentUuids { | |||
private final AnalysisMetadataHolder analysisMetadataHolder; | |||
private final DbClient dbClient; | |||
private Map<String, String> mergeBranchComponentsUuidsByKey; | |||
private Map<String, String> targetBranchComponentsUuidsByKey; | |||
private String mergeBranchName; | |||
private boolean hasMergeBranchAnalysis; | |||
private boolean hasTargetBranchAnalysis; | |||
@CheckForNull | |||
private String targetBranchUuid; | |||
public MergeAndTargetBranchComponentUuids(AnalysisMetadataHolder analysisMetadataHolder, DbClient dbClient) { | |||
this.analysisMetadataHolder = analysisMetadataHolder; | |||
this.dbClient = dbClient; | |||
} | |||
private void lazyInit() { | |||
if (mergeBranchComponentsUuidsByKey == null) { | |||
String mergeBranchUuid = analysisMetadataHolder.getBranch().getMergeBranchUuid(); | |||
mergeBranchComponentsUuidsByKey = new HashMap<>(); | |||
targetBranchComponentsUuidsByKey = new HashMap<>(); | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
Optional<BranchDto> opt = dbClient.branchDao().selectByUuid(dbSession, mergeBranchUuid); | |||
checkState(opt.isPresent(), "Merge branch '%s' does not exist", mergeBranchUuid); | |||
mergeBranchName = opt.get().getKey(); | |||
initForMergeBranch(mergeBranchUuid, dbSession); | |||
if (analysisMetadataHolder.isPullRequest()) { | |||
initForTargetBranch(mergeBranchUuid, dbSession); | |||
} else { | |||
hasTargetBranchAnalysis = false; | |||
} | |||
} | |||
} | |||
} | |||
private void initForTargetBranch(String mergeBranchUuid, DbSession dbSession) { | |||
Optional<BranchDto> branchDtoOpt = dbClient.branchDao().selectByBranchKey(dbSession, analysisMetadataHolder.getProject().getUuid(), | |||
analysisMetadataHolder.getBranch().getTargetBranchName()); | |||
targetBranchUuid = branchDtoOpt.map(BranchDto::getUuid).orElse(null); | |||
hasTargetBranchAnalysis = targetBranchUuid != null && dbClient.snapshotDao().selectLastAnalysisByRootComponentUuid(dbSession, targetBranchUuid).isPresent(); | |||
if (hasTargetBranchAnalysis && !targetBranchUuid.equals(mergeBranchUuid)) { | |||
List<ComponentDto> targetComponents = dbClient.componentDao().selectByProjectUuid(targetBranchUuid, dbSession); | |||
for (ComponentDto dto : targetComponents) { | |||
targetBranchComponentsUuidsByKey.put(dto.getKey(), dto.uuid()); | |||
} | |||
} | |||
} | |||
private void initForMergeBranch(String mergeBranchUuid, DbSession dbSession) { | |||
hasMergeBranchAnalysis = dbClient.snapshotDao().selectLastAnalysisByRootComponentUuid(dbSession, mergeBranchUuid).isPresent(); | |||
if (hasMergeBranchAnalysis) { | |||
List<ComponentDto> components = dbClient.componentDao().selectByProjectUuid(mergeBranchUuid, dbSession); | |||
for (ComponentDto dto : components) { | |||
mergeBranchComponentsUuidsByKey.put(dto.getKey(), dto.uuid()); | |||
} | |||
} | |||
} | |||
public boolean hasMergeBranchAnalysis() { | |||
lazyInit(); | |||
return hasMergeBranchAnalysis; | |||
} | |||
public boolean hasTargetBranchAnalysis() { | |||
lazyInit(); | |||
return hasTargetBranchAnalysis; | |||
} | |||
public String getMergeBranchName() { | |||
lazyInit(); | |||
return mergeBranchName; | |||
} | |||
public boolean areTargetAndMergeBranchesDifferent() { | |||
lazyInit(); | |||
return targetBranchUuid == null || !analysisMetadataHolder.getBranch().getMergeBranchUuid().equals(targetBranchUuid); | |||
} | |||
@CheckForNull | |||
public String getMergeBranchComponentUuid(String dbKey) { | |||
lazyInit(); | |||
String cleanComponentKey = removeBranchAndPullRequestFromKey(dbKey); | |||
return mergeBranchComponentsUuidsByKey.get(cleanComponentKey); | |||
} | |||
@CheckForNull | |||
public String getTargetBranchComponentUuid(String dbKey) { | |||
lazyInit(); | |||
String cleanComponentKey = removeBranchAndPullRequestFromKey(dbKey); | |||
return targetBranchComponentsUuidsByKey.get(cleanComponentKey); | |||
} | |||
} |
@@ -35,7 +35,7 @@ public class ProjectViewAttributes { | |||
public ProjectViewAttributes(String projectUuid, String originalKey, @Nullable Long analysisDate, @Nullable String branchName) { | |||
this.projectUuid = requireNonNull(projectUuid, "projectUuid can't be null"); | |||
this.originalKey = requireNonNull(originalKey, "projectKey can't be null");; | |||
this.originalKey = requireNonNull(originalKey, "projectKey can't be null"); | |||
this.analysisDate = analysisDate; | |||
this.branchName = branchName; | |||
} |
@@ -0,0 +1,95 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2019 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program 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. | |||
* | |||
* This program 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.ce.task.projectanalysis.component; | |||
import java.util.HashMap; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.Optional; | |||
import javax.annotation.CheckForNull; | |||
import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.component.BranchDto; | |||
import org.sonar.db.component.ComponentDto; | |||
import static com.google.common.base.Preconditions.checkState; | |||
import static org.sonar.db.component.ComponentDto.removeBranchAndPullRequestFromKey; | |||
/** | |||
* Cache a map between component keys and uuids in the reference branch | |||
*/ | |||
public class ReferenceBranchComponentUuids { | |||
private final AnalysisMetadataHolder analysisMetadataHolder; | |||
private final DbClient dbClient; | |||
private Map<String, String> referenceBranchComponentsUuidsByKey; | |||
private String referenceBranchName; | |||
private boolean hasReferenceBranchAnalysis; | |||
public ReferenceBranchComponentUuids(AnalysisMetadataHolder analysisMetadataHolder, DbClient dbClient) { | |||
this.analysisMetadataHolder = analysisMetadataHolder; | |||
this.dbClient = dbClient; | |||
} | |||
private void lazyInit() { | |||
if (referenceBranchComponentsUuidsByKey == null) { | |||
String referenceBranchUuid = analysisMetadataHolder.getBranch().getReferenceBranchUuid(); | |||
referenceBranchComponentsUuidsByKey = new HashMap<>(); | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
Optional<BranchDto> opt = dbClient.branchDao().selectByUuid(dbSession, referenceBranchUuid); | |||
checkState(opt.isPresent(), "Reference branch '%s' does not exist", referenceBranchUuid); | |||
referenceBranchName = opt.get().getKey(); | |||
init(referenceBranchUuid, dbSession); | |||
} | |||
} | |||
} | |||
private void init(String referenceBranchUuid, DbSession dbSession) { | |||
hasReferenceBranchAnalysis = dbClient.snapshotDao().selectLastAnalysisByRootComponentUuid(dbSession, referenceBranchUuid).isPresent(); | |||
if (hasReferenceBranchAnalysis) { | |||
List<ComponentDto> components = dbClient.componentDao().selectByProjectUuid(referenceBranchUuid, dbSession); | |||
for (ComponentDto dto : components) { | |||
referenceBranchComponentsUuidsByKey.put(dto.getKey(), dto.uuid()); | |||
} | |||
} | |||
} | |||
public boolean hasReferenceBranchAnalysis() { | |||
lazyInit(); | |||
return hasReferenceBranchAnalysis; | |||
} | |||
public String getReferenceBranchName() { | |||
lazyInit(); | |||
return referenceBranchName; | |||
} | |||
@CheckForNull | |||
public String getComponentUuid(String dbKey) { | |||
lazyInit(); | |||
String cleanComponentKey = removeBranchAndPullRequestFromKey(dbKey); | |||
return referenceBranchComponentsUuidsByKey.get(cleanComponentKey); | |||
} | |||
} |
@@ -53,14 +53,13 @@ public class SiblingComponentsWithOpenIssues { | |||
String referenceBranchUuid; | |||
if (metadataHolder.isPullRequest()) { | |||
referenceBranchUuid = metadataHolder.getBranch().getMergeBranchUuid(); | |||
referenceBranchUuid = metadataHolder.getBranch().getReferenceBranchUuid(); | |||
} else { | |||
referenceBranchUuid = currentBranchUuid; | |||
} | |||
uuidsByKey = new HashMap<>(); | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
// for the time being it still tries to load from short living branches | |||
List<KeyWithUuidDto> components = dbClient.componentDao().selectAllSiblingComponentKeysHavingOpenIssues(dbSession, referenceBranchUuid, currentBranchUuid); | |||
for (KeyWithUuidDto dto : components) { | |||
uuidsByKey.computeIfAbsent(removeBranchAndPullRequestFromKey(dto.key()), s -> new HashSet<>()).add(dto.uuid()); |
@@ -34,7 +34,7 @@ import org.sonar.ce.task.projectanalysis.component.BranchPersisterImpl; | |||
import org.sonar.ce.task.projectanalysis.component.ConfigurationRepositoryImpl; | |||
import org.sonar.ce.task.projectanalysis.component.DbIdsRepositoryImpl; | |||
import org.sonar.ce.task.projectanalysis.component.DisabledComponentsHolderImpl; | |||
import org.sonar.ce.task.projectanalysis.component.MergeAndTargetBranchComponentUuids; | |||
import org.sonar.ce.task.projectanalysis.component.ReferenceBranchComponentUuids; | |||
import org.sonar.ce.task.projectanalysis.component.ReportModulesPath; | |||
import org.sonar.ce.task.projectanalysis.component.SiblingComponentsWithOpenIssues; | |||
import org.sonar.ce.task.projectanalysis.component.TreeRootHolderImpl; | |||
@@ -82,7 +82,7 @@ import org.sonar.ce.task.projectanalysis.issue.SiblingsIssueMerger; | |||
import org.sonar.ce.task.projectanalysis.issue.SiblingsIssuesLoader; | |||
import org.sonar.ce.task.projectanalysis.issue.TrackerBaseInputFactory; | |||
import org.sonar.ce.task.projectanalysis.issue.TrackerExecution; | |||
import org.sonar.ce.task.projectanalysis.issue.TrackerMergeOrTargetBranchInputFactory; | |||
import org.sonar.ce.task.projectanalysis.issue.TrackerReferenceBranchInputFactory; | |||
import org.sonar.ce.task.projectanalysis.issue.TrackerRawInputFactory; | |||
import org.sonar.ce.task.projectanalysis.issue.UpdateConflictResolver; | |||
import org.sonar.ce.task.projectanalysis.issue.commonrule.BranchCoverageRule; | |||
@@ -198,7 +198,7 @@ public final class ProjectAnalysisTaskContainerPopulator implements ContainerPop | |||
MeasureComputersHolderImpl.class, | |||
MutableTaskResultHolderImpl.class, | |||
BatchReportReaderImpl.class, | |||
MergeAndTargetBranchComponentUuids.class, | |||
ReferenceBranchComponentUuids.class, | |||
SiblingComponentsWithOpenIssues.class, | |||
// repositories | |||
@@ -274,7 +274,7 @@ public final class ProjectAnalysisTaskContainerPopulator implements ContainerPop | |||
UpdateConflictResolver.class, | |||
TrackerBaseInputFactory.class, | |||
TrackerRawInputFactory.class, | |||
TrackerMergeOrTargetBranchInputFactory.class, | |||
TrackerReferenceBranchInputFactory.class, | |||
ClosedIssuesInputFactory.class, | |||
Tracker.class, | |||
TrackerExecution.class, |
@@ -24,7 +24,7 @@ import java.util.Map; | |||
import java.util.stream.Stream; | |||
import org.sonar.ce.task.projectanalysis.component.Component; | |||
import org.sonar.ce.task.projectanalysis.component.CrawlerDepthLimit; | |||
import org.sonar.ce.task.projectanalysis.component.MergeAndTargetBranchComponentUuids; | |||
import org.sonar.ce.task.projectanalysis.component.ReferenceBranchComponentUuids; | |||
import org.sonar.ce.task.projectanalysis.component.TypeAwareVisitorAdapter; | |||
import org.sonar.ce.task.projectanalysis.util.cache.DiskCache; | |||
import org.sonar.core.issue.DefaultIssue; | |||
@@ -39,17 +39,17 @@ public class IntegrateIssuesVisitor extends TypeAwareVisitorAdapter { | |||
private final IssueVisitors issueVisitors; | |||
private final IssueTrackingDelegator issueTracking; | |||
private final SiblingsIssueMerger issueStatusCopier; | |||
private final MergeAndTargetBranchComponentUuids mergeAndTargetBranchComponentUuids; | |||
private final ReferenceBranchComponentUuids referenceBranchComponentUuids; | |||
public IntegrateIssuesVisitor(IssueCache issueCache, IssueLifecycle issueLifecycle, IssueVisitors issueVisitors, IssueTrackingDelegator issueTracking, | |||
SiblingsIssueMerger issueStatusCopier, MergeAndTargetBranchComponentUuids mergeAndTargetBranchComponentUuids) { | |||
SiblingsIssueMerger issueStatusCopier, ReferenceBranchComponentUuids referenceBranchComponentUuids) { | |||
super(CrawlerDepthLimit.FILE, POST_ORDER); | |||
this.issueCache = issueCache; | |||
this.issueLifecycle = issueLifecycle; | |||
this.issueVisitors = issueVisitors; | |||
this.issueTracking = issueTracking; | |||
this.issueStatusCopier = issueStatusCopier; | |||
this.mergeAndTargetBranchComponentUuids = mergeAndTargetBranchComponentUuids; | |||
this.referenceBranchComponentUuids = referenceBranchComponentUuids; | |||
} | |||
@Override | |||
@@ -87,7 +87,7 @@ public class IntegrateIssuesVisitor extends TypeAwareVisitorAdapter { | |||
for (Map.Entry<DefaultIssue, DefaultIssue> entry : matched.entrySet()) { | |||
DefaultIssue raw = entry.getKey(); | |||
DefaultIssue base = entry.getValue(); | |||
issueLifecycle.copyExistingOpenIssueFromLongLivingBranch(raw, base, mergeAndTargetBranchComponentUuids.getMergeBranchName()); | |||
issueLifecycle.copyExistingOpenIssueFromBranch(raw, base, referenceBranchComponentUuids.getReferenceBranchName()); | |||
process(component, raw, cacheAppender); | |||
} | |||
} |
@@ -97,21 +97,21 @@ public class IssueLifecycle { | |||
} | |||
} | |||
public void copyExistingOpenIssueFromLongLivingBranch(DefaultIssue raw, DefaultIssue base, String fromLongBranchName) { | |||
public void copyExistingOpenIssueFromBranch(DefaultIssue raw, DefaultIssue base, String branchName) { | |||
raw.setKey(Uuids.create()); | |||
raw.setNew(false); | |||
copyAttributesOfIssueFromOtherBranch(raw, base); | |||
raw.setFieldChange(changeContext, IssueFieldsSetter.FROM_LONG_BRANCH, fromLongBranchName, analysisMetadataHolder.getBranch().getName()); | |||
copyAttributesOfIssueFromAnotherBranch(raw, base); | |||
raw.setFieldChange(changeContext, IssueFieldsSetter.FROM_BRANCH, branchName, analysisMetadataHolder.getBranch().getName()); | |||
} | |||
public void mergeConfirmedOrResolvedFromShortLivingBranchOrPr(DefaultIssue raw, DefaultIssue base, KeyType branchType, String fromShortBranchNameOrPR) { | |||
copyAttributesOfIssueFromOtherBranch(raw, base); | |||
String from = (branchType == KeyType.PULL_REQUEST ? "#" : "") + fromShortBranchNameOrPR; | |||
public void mergeConfirmedOrResolvedFromPr(DefaultIssue raw, DefaultIssue base, String pr) { | |||
copyAttributesOfIssueFromAnotherBranch(raw, base); | |||
String from = "#" + pr; | |||
String to = analysisMetadataHolder.isPullRequest() ? ("#" + analysisMetadataHolder.getPullRequestKey()) : analysisMetadataHolder.getBranch().getName(); | |||
raw.setFieldChange(changeContext, IssueFieldsSetter.FROM_SHORT_BRANCH, from, to); | |||
raw.setFieldChange(changeContext, IssueFieldsSetter.FROM_BRANCH, from, to); | |||
} | |||
private void copyAttributesOfIssueFromOtherBranch(DefaultIssue to, DefaultIssue from) { | |||
private void copyAttributesOfIssueFromAnotherBranch(DefaultIssue to, DefaultIssue from) { | |||
to.setCopied(true); | |||
copyFields(to, from); | |||
if (from.manualSeverity()) { |
@@ -19,15 +19,13 @@ | |||
*/ | |||
package org.sonar.ce.task.projectanalysis.issue; | |||
import java.util.stream.Stream; | |||
import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder; | |||
import org.sonar.ce.task.projectanalysis.analysis.Branch; | |||
import org.sonar.ce.task.projectanalysis.component.Component; | |||
import org.sonar.core.issue.DefaultIssue; | |||
import org.sonar.core.issue.tracking.Tracking; | |||
import org.sonar.db.component.BranchType; | |||
import static java.util.Collections.emptyMap; | |||
import static java.util.stream.Stream.empty; | |||
public class IssueTrackingDelegator { | |||
private final PullRequestTrackerExecution pullRequestTracker; | |||
@@ -36,7 +34,7 @@ public class IssueTrackingDelegator { | |||
private final ReferenceBranchTrackerExecution referenceBranchTracker; | |||
public IssueTrackingDelegator(PullRequestTrackerExecution pullRequestTracker, ReferenceBranchTrackerExecution referenceBranchTracker, | |||
TrackerExecution tracker, AnalysisMetadataHolder analysisMetadataHolder) { | |||
TrackerExecution tracker, AnalysisMetadataHolder analysisMetadataHolder) { | |||
this.pullRequestTracker = pullRequestTracker; | |||
this.referenceBranchTracker = referenceBranchTracker; | |||
this.tracker = tracker; | |||
@@ -48,7 +46,7 @@ public class IssueTrackingDelegator { | |||
return standardResult(pullRequestTracker.track(component)); | |||
} else if (isFirstAnalysisSecondaryBranch()) { | |||
Tracking<DefaultIssue, DefaultIssue> tracking = referenceBranchTracker.track(component); | |||
return new TrackingResult(tracking.getMatchedRaws(), emptyMap(), Stream.empty(), tracking.getUnmatchedRaws()); | |||
return new TrackingResult(tracking.getMatchedRaws(), emptyMap(), empty(), tracking.getUnmatchedRaws()); | |||
} else { | |||
return standardResult(tracker.track(component)); | |||
} | |||
@@ -59,12 +57,11 @@ public class IssueTrackingDelegator { | |||
} | |||
/** | |||
* Special case where we want to do the issue tracking with the merge branch, and copy matched issue to the current branch. | |||
* Special case where we want to do the issue tracking with the reference branch, and copy matched issue to the current branch. | |||
*/ | |||
private boolean isFirstAnalysisSecondaryBranch() { | |||
if (analysisMetadataHolder.isFirstAnalysis()) { | |||
Branch branch = analysisMetadataHolder.getBranch(); | |||
return !branch.isMain(); | |||
return !analysisMetadataHolder.getBranch().isMain(); | |||
} | |||
return false; | |||
} |
@@ -50,11 +50,11 @@ public class PullRequestTrackerExecution { | |||
Input<DefaultIssue> rawInput = rawInputFactory.create(component); | |||
Input<DefaultIssue> previousAnalysisInput = baseInputFactory.create(component); | |||
// Step 1: if there is no analysis or merge or target branch, keep only issues on changed lines | |||
// Step 1: only keep issues on changed lines | |||
List<DefaultIssue> filteredRaws = keepIssuesHavingAtLeastOneLocationOnChangedLines(component, rawInput.getIssues()); | |||
Input<DefaultIssue> unmatchedRawsAfterChangedLineFiltering = new DefaultTrackingInput(filteredRaws, rawInput.getLineHashSequence(), rawInput.getBlockHashSequence()); | |||
// Step 2: track issues of previous analysis of the current PR | |||
// Step 2: track issues with previous analysis of the current PR | |||
return tracker.trackNonClosed(unmatchedRawsAfterChangedLineFiltering, previousAnalysisInput); | |||
} | |||
@@ -67,8 +67,7 @@ public class PullRequestTrackerExecution { | |||
return Collections.emptyList(); | |||
} | |||
final Set<Integer> newLines = newLinesOpt.get(); | |||
return issues | |||
.stream() | |||
return issues.stream() | |||
.filter(i -> IssueLocations.allLinesFor(i, component.getUuid()).anyMatch(newLines::contains)) | |||
.collect(Collectors.toList()); | |||
} |
@@ -26,17 +26,17 @@ import org.sonar.core.issue.tracking.Tracking; | |||
public class ReferenceBranchTrackerExecution { | |||
private final TrackerRawInputFactory rawInputFactory; | |||
private final TrackerMergeOrTargetBranchInputFactory mergeInputFactory; | |||
private final TrackerReferenceBranchInputFactory referenceBranchInputFactory; | |||
private final Tracker<DefaultIssue, DefaultIssue> tracker; | |||
public ReferenceBranchTrackerExecution(TrackerRawInputFactory rawInputFactory, TrackerMergeOrTargetBranchInputFactory mergeInputFactory, | |||
public ReferenceBranchTrackerExecution(TrackerRawInputFactory rawInputFactory, TrackerReferenceBranchInputFactory referenceBranchInputFactory, | |||
Tracker<DefaultIssue, DefaultIssue> tracker) { | |||
this.rawInputFactory = rawInputFactory; | |||
this.mergeInputFactory = mergeInputFactory; | |||
this.referenceBranchInputFactory = referenceBranchInputFactory; | |||
this.tracker = tracker; | |||
} | |||
public Tracking<DefaultIssue, DefaultIssue> track(Component component) { | |||
return tracker.trackNonClosed(rawInputFactory.create(component), mergeInputFactory.createForMergeBranch(component)); | |||
return tracker.trackNonClosed(rawInputFactory.create(component), referenceBranchInputFactory.create(component)); | |||
} | |||
} |
@@ -25,7 +25,6 @@ import javax.annotation.Nullable; | |||
import javax.annotation.concurrent.Immutable; | |||
import org.sonar.api.rule.RuleKey; | |||
import org.sonar.core.issue.tracking.Trackable; | |||
import org.sonar.db.component.KeyType; | |||
@Immutable | |||
public class SiblingIssue implements Trackable { | |||
@@ -35,20 +34,17 @@ public class SiblingIssue implements Trackable { | |||
private final String lineHash; | |||
private final RuleKey ruleKey; | |||
private final String status; | |||
private final String branchKey; | |||
private final KeyType branchType; | |||
private final String prKey; | |||
private final Date updateDate; | |||
public SiblingIssue(String key, @Nullable Integer line, String message, @Nullable String lineHash, RuleKey ruleKey, String status, String branchKey, KeyType branchType, | |||
Date updateDate) { | |||
SiblingIssue(String key, @Nullable Integer line, @Nullable String message, @Nullable String lineHash, RuleKey ruleKey, String status, String prKey, Date updateDate) { | |||
this.key = key; | |||
this.line = line; | |||
this.message = message; | |||
this.lineHash = lineHash; | |||
this.ruleKey = ruleKey; | |||
this.status = status; | |||
this.branchKey = branchKey; | |||
this.branchType = branchType; | |||
this.prKey = prKey; | |||
this.updateDate = updateDate; | |||
} | |||
@@ -62,6 +58,7 @@ public class SiblingIssue implements Trackable { | |||
return line; | |||
} | |||
@CheckForNull | |||
@Override | |||
public String getMessage() { | |||
return message; | |||
@@ -83,12 +80,8 @@ public class SiblingIssue implements Trackable { | |||
return status; | |||
} | |||
public String getBranchKey() { | |||
return branchKey; | |||
} | |||
public KeyType getBranchType() { | |||
return branchType; | |||
public String getPrKey() { | |||
return prKey; | |||
} | |||
@Override |
@@ -42,7 +42,7 @@ public class SiblingsIssueMerger { | |||
} | |||
/** | |||
* Look for all unclosed issues in branches/PR targeting the same long living branch, and run | |||
* Look for all unclosed issues in PR targeting the same branch, and run | |||
* a light issue tracking to find matches. Then merge issue attributes in the new issues. | |||
*/ | |||
public void tryMerge(Component component, Collection<DefaultIssue> newIssues) { | |||
@@ -55,7 +55,7 @@ public class SiblingsIssueMerger { | |||
for (Map.Entry<DefaultIssue, SiblingIssue> e : matchedRaws.entrySet()) { | |||
SiblingIssue issue = e.getValue(); | |||
issueLifecycle.mergeConfirmedOrResolvedFromShortLivingBranchOrPr(e.getKey(), defaultIssues.get(issue), issue.getBranchType(), issue.getBranchKey()); | |||
issueLifecycle.mergeConfirmedOrResolvedFromPr(e.getKey(), defaultIssues.get(issue), issue.getPrKey()); | |||
} | |||
} | |||
} |
@@ -25,12 +25,14 @@ import java.util.List; | |||
import java.util.Map; | |||
import java.util.Set; | |||
import java.util.stream.Collectors; | |||
import org.sonar.api.utils.Preconditions; | |||
import org.sonar.ce.task.projectanalysis.component.Component; | |||
import org.sonar.ce.task.projectanalysis.component.SiblingComponentsWithOpenIssues; | |||
import org.sonar.core.issue.DefaultIssue; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.component.ComponentDto; | |||
import org.sonar.db.component.KeyType; | |||
import org.sonar.db.issue.IssueDto; | |||
import org.sonar.db.issue.PrIssueDto; | |||
@@ -45,7 +47,7 @@ public class SiblingsIssuesLoader { | |||
private final ComponentIssuesLoader componentIssuesLoader; | |||
public SiblingsIssuesLoader(SiblingComponentsWithOpenIssues siblingComponentsWithOpenIssues, DbClient dbClient, | |||
ComponentIssuesLoader componentIssuesLoader) { | |||
ComponentIssuesLoader componentIssuesLoader) { | |||
this.siblingComponentsWithOpenIssues = siblingComponentsWithOpenIssues; | |||
this.dbClient = dbClient; | |||
this.componentIssuesLoader = componentIssuesLoader; | |||
@@ -67,7 +69,8 @@ public class SiblingsIssuesLoader { | |||
} | |||
private static SiblingIssue toSiblingIssue(PrIssueDto dto) { | |||
return new SiblingIssue(dto.getKey(), dto.getLine(), dto.getMessage(), dto.getChecksum(), dto.getRuleKey(), dto.getStatus(), dto.getBranchKey(), dto.getKeyType(), | |||
Preconditions.checkState(dto.getKeyType().equals(KeyType.PULL_REQUEST), "Expected all issues to belong to P/Rs"); | |||
return new SiblingIssue(dto.getKey(), dto.getLine(), dto.getMessage(), dto.getChecksum(), dto.getRuleKey(), dto.getStatus(), dto.getBranchKey(), | |||
longToDate(dto.getIssueUpdateDate())); | |||
} | |||
@@ -277,7 +277,7 @@ public class TrackerRawInputFactory { | |||
private Optional<DbIssues.Location> convertLocation(ScannerReport.IssueLocation source) { | |||
DbIssues.Location.Builder target = DbIssues.Location.newBuilder(); | |||
if (source.getComponentRef() != 0 && source.getComponentRef() != component.getReportAttributes().getRef()) { | |||
// SONAR-10781 Component might not exist because on short living branch and PR, only changed components are included in the report | |||
// SONAR-10781 Component might not exist because on PR, only changed components are included in the report | |||
Optional<Component> optionalComponent = treeRootHolder.getOptionalComponentByRef(source.getComponentRef()); | |||
if (!optionalComponent.isPresent()) { | |||
return Optional.empty(); |
@@ -23,7 +23,7 @@ import java.util.Collections; | |||
import java.util.List; | |||
import javax.annotation.Nullable; | |||
import org.sonar.ce.task.projectanalysis.component.Component; | |||
import org.sonar.ce.task.projectanalysis.component.MergeAndTargetBranchComponentUuids; | |||
import org.sonar.ce.task.projectanalysis.component.ReferenceBranchComponentUuids; | |||
import org.sonar.core.issue.DefaultIssue; | |||
import org.sonar.core.issue.tracking.Input; | |||
import org.sonar.core.issue.tracking.LazyInput; | |||
@@ -31,60 +31,42 @@ import org.sonar.core.issue.tracking.LineHashSequence; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
public class TrackerMergeOrTargetBranchInputFactory { | |||
public class TrackerReferenceBranchInputFactory { | |||
private static final LineHashSequence EMPTY_LINE_HASH_SEQUENCE = new LineHashSequence(Collections.emptyList()); | |||
private final ComponentIssuesLoader componentIssuesLoader; | |||
private final DbClient dbClient; | |||
private final MergeAndTargetBranchComponentUuids mergeAndTargetBranchComponentUuids; | |||
private final ReferenceBranchComponentUuids referenceBranchComponentUuids; | |||
public TrackerMergeOrTargetBranchInputFactory(ComponentIssuesLoader componentIssuesLoader, MergeAndTargetBranchComponentUuids mergeAndTargetBranchComponentUuids, | |||
DbClient dbClient) { | |||
public TrackerReferenceBranchInputFactory(ComponentIssuesLoader componentIssuesLoader, ReferenceBranchComponentUuids referenceBranchComponentUuids, DbClient dbClient) { | |||
this.componentIssuesLoader = componentIssuesLoader; | |||
this.mergeAndTargetBranchComponentUuids = mergeAndTargetBranchComponentUuids; | |||
this.referenceBranchComponentUuids = referenceBranchComponentUuids; | |||
this.dbClient = dbClient; | |||
// TODO detect file moves? | |||
} | |||
public boolean hasMergeBranchAnalysis() { | |||
return mergeAndTargetBranchComponentUuids.hasMergeBranchAnalysis(); | |||
public Input<DefaultIssue> create(Component component) { | |||
String referenceBranchComponentUuid = referenceBranchComponentUuids.getComponentUuid(component.getDbKey()); | |||
return new ReferenceLazyInput(component.getType(), referenceBranchComponentUuid); | |||
} | |||
public boolean hasTargetBranchAnalysis() { | |||
return mergeAndTargetBranchComponentUuids.hasTargetBranchAnalysis(); | |||
} | |||
public boolean areTargetAndMergeBranchesDifferent() { | |||
return mergeAndTargetBranchComponentUuids.areTargetAndMergeBranchesDifferent(); | |||
} | |||
public Input<DefaultIssue> createForMergeBranch(Component component) { | |||
String mergeBranchComponentUuid = mergeAndTargetBranchComponentUuids.getMergeBranchComponentUuid(component.getDbKey()); | |||
return new MergeOrTargetLazyInput(component.getType(), mergeBranchComponentUuid); | |||
} | |||
public Input<DefaultIssue> createForTargetBranch(Component component) { | |||
String targetBranchComponentUuid = mergeAndTargetBranchComponentUuids.getTargetBranchComponentUuid(component.getDbKey()); | |||
return new MergeOrTargetLazyInput(component.getType(), targetBranchComponentUuid); | |||
} | |||
private class MergeOrTargetLazyInput extends LazyInput<DefaultIssue> { | |||
private class ReferenceLazyInput extends LazyInput<DefaultIssue> { | |||
private final Component.Type type; | |||
private final String mergeOrTargetBranchComponentUuid; | |||
private final String referenceBranchComponentUuid; | |||
private MergeOrTargetLazyInput(Component.Type type, @Nullable String mergeOrTargetBranchComponentUuid) { | |||
private ReferenceLazyInput(Component.Type type, @Nullable String referenceBranchComponentUuid) { | |||
this.type = type; | |||
this.mergeOrTargetBranchComponentUuid = mergeOrTargetBranchComponentUuid; | |||
this.referenceBranchComponentUuid = referenceBranchComponentUuid; | |||
} | |||
@Override | |||
protected LineHashSequence loadLineHashSequence() { | |||
if (mergeOrTargetBranchComponentUuid == null || type != Component.Type.FILE) { | |||
if (referenceBranchComponentUuid == null || type != Component.Type.FILE) { | |||
return EMPTY_LINE_HASH_SEQUENCE; | |||
} | |||
try (DbSession session = dbClient.openSession(false)) { | |||
List<String> hashes = dbClient.fileSourceDao().selectLineHashes(session, mergeOrTargetBranchComponentUuid); | |||
List<String> hashes = dbClient.fileSourceDao().selectLineHashes(session, referenceBranchComponentUuid); | |||
if (hashes == null || hashes.isEmpty()) { | |||
return EMPTY_LINE_HASH_SEQUENCE; | |||
} | |||
@@ -94,10 +76,10 @@ public class TrackerMergeOrTargetBranchInputFactory { | |||
@Override | |||
protected List<DefaultIssue> loadIssues() { | |||
if (mergeOrTargetBranchComponentUuid == null) { | |||
if (referenceBranchComponentUuid == null) { | |||
return Collections.emptyList(); | |||
} | |||
return componentIssuesLoader.loadOpenIssuesWithChanges(mergeOrTargetBranchComponentUuid); | |||
return componentIssuesLoader.loadOpenIssuesWithChanges(referenceBranchComponentUuid); | |||
} | |||
} | |||
@@ -25,7 +25,7 @@ import org.sonar.api.utils.log.Loggers; | |||
import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder; | |||
import org.sonar.ce.task.projectanalysis.analysis.Branch; | |||
import org.sonar.ce.task.projectanalysis.component.Component; | |||
import org.sonar.ce.task.projectanalysis.component.MergeAndTargetBranchComponentUuids; | |||
import org.sonar.ce.task.projectanalysis.component.ReferenceBranchComponentUuids; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.source.FileSourceDto; | |||
@@ -35,12 +35,12 @@ public class ScmInfoDbLoader { | |||
private final AnalysisMetadataHolder analysisMetadataHolder; | |||
private final DbClient dbClient; | |||
private final MergeAndTargetBranchComponentUuids mergeBranchComponentUuid; | |||
private final ReferenceBranchComponentUuids referenceBranchComponentUuid; | |||
public ScmInfoDbLoader(AnalysisMetadataHolder analysisMetadataHolder, DbClient dbClient, MergeAndTargetBranchComponentUuids mergeBranchComponentUuid) { | |||
public ScmInfoDbLoader(AnalysisMetadataHolder analysisMetadataHolder, DbClient dbClient, ReferenceBranchComponentUuids referenceBranchComponentUuid) { | |||
this.analysisMetadataHolder = analysisMetadataHolder; | |||
this.dbClient = dbClient; | |||
this.mergeBranchComponentUuid = mergeBranchComponentUuid; | |||
this.referenceBranchComponentUuid = referenceBranchComponentUuid; | |||
} | |||
public Optional<DbScmInfo> getScmInfo(Component file) { | |||
@@ -67,11 +67,7 @@ public class ScmInfoDbLoader { | |||
// at this point, it's the first analysis of a branch with copyFromPrevious flag true or any analysis of a PR | |||
Branch branch = analysisMetadataHolder.getBranch(); | |||
if (!branch.isMain()) { | |||
String uuid = mergeBranchComponentUuid.getTargetBranchComponentUuid(file.getDbKey()); | |||
if (uuid == null) { | |||
uuid = mergeBranchComponentUuid.getMergeBranchComponentUuid(file.getDbKey()); | |||
} | |||
return Optional.ofNullable(uuid); | |||
return Optional.ofNullable(referenceBranchComponentUuid.getComponentUuid(file.getDbKey())); | |||
} | |||
return Optional.empty(); |
@@ -23,7 +23,7 @@ import java.util.Collections; | |||
import java.util.List; | |||
import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder; | |||
import org.sonar.ce.task.projectanalysis.component.Component; | |||
import org.sonar.ce.task.projectanalysis.component.MergeAndTargetBranchComponentUuids; | |||
import org.sonar.ce.task.projectanalysis.component.ReferenceBranchComponentUuids; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.source.FileSourceDao; | |||
@@ -33,15 +33,15 @@ public class SourceLinesDiffImpl implements SourceLinesDiff { | |||
private final DbClient dbClient; | |||
private final FileSourceDao fileSourceDao; | |||
private final SourceLinesHashRepository sourceLinesHash; | |||
private final MergeAndTargetBranchComponentUuids mergeAndTargetBranchComponentUuids; | |||
private final ReferenceBranchComponentUuids referenceBranchComponentUuids; | |||
private final AnalysisMetadataHolder analysisMetadataHolder; | |||
public SourceLinesDiffImpl(DbClient dbClient, FileSourceDao fileSourceDao, SourceLinesHashRepository sourceLinesHash, | |||
MergeAndTargetBranchComponentUuids mergeAndTargetBranchComponentUuids, AnalysisMetadataHolder analysisMetadataHolder) { | |||
ReferenceBranchComponentUuids referenceBranchComponentUuids, AnalysisMetadataHolder analysisMetadataHolder) { | |||
this.dbClient = dbClient; | |||
this.fileSourceDao = fileSourceDao; | |||
this.sourceLinesHash = sourceLinesHash; | |||
this.mergeAndTargetBranchComponentUuids = mergeAndTargetBranchComponentUuids; | |||
this.referenceBranchComponentUuids = referenceBranchComponentUuids; | |||
this.analysisMetadataHolder = analysisMetadataHolder; | |||
} | |||
@@ -57,10 +57,7 @@ public class SourceLinesDiffImpl implements SourceLinesDiff { | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
String uuid; | |||
if (analysisMetadataHolder.isPullRequest()) { | |||
uuid = mergeAndTargetBranchComponentUuids.getTargetBranchComponentUuid(component.getDbKey()); | |||
if (uuid == null) { | |||
uuid = mergeAndTargetBranchComponentUuids.getMergeBranchComponentUuid(component.getDbKey()); | |||
} | |||
uuid = referenceBranchComponentUuids.getComponentUuid(component.getDbKey()); | |||
} else { | |||
uuid = component.getUuid(); | |||
} |
@@ -90,11 +90,11 @@ public class ValidateProjectStep implements ComputationStep { | |||
if (!analysisMetadataHolder.isPullRequest()) { | |||
return; | |||
} | |||
String mergeBranchUuid = analysisMetadataHolder.getBranch().getMergeBranchUuid(); | |||
int moduleCount = dbClient.componentDao().countEnabledModulesByProjectUuid(session, mergeBranchUuid); | |||
String referenceBranchUuid = analysisMetadataHolder.getBranch().getReferenceBranchUuid(); | |||
int moduleCount = dbClient.componentDao().countEnabledModulesByProjectUuid(session, referenceBranchUuid); | |||
if (moduleCount > 0) { | |||
Optional<BranchDto> opt = dbClient.branchDao().selectByUuid(session, mergeBranchUuid); | |||
checkState(opt.isPresent(), "Merge branch '%s' does not exist", mergeBranchUuid); | |||
Optional<BranchDto> opt = dbClient.branchDao().selectByUuid(session, referenceBranchUuid); | |||
checkState(opt.isPresent(), "Reference branch '%s' does not exist", referenceBranchUuid); | |||
throw MessageException.of(String.format( | |||
"Due to an upgrade, you need first to re-analyze the target branch '%s' before analyzing this pull request.", opt.get().getKey())); | |||
} |
@@ -289,7 +289,7 @@ public class PostProjectAnalysisTasksExecutorTest { | |||
} | |||
@Override | |||
public String getMergeBranchUuid() { | |||
public String getReferenceBranchUuid() { | |||
throw new UnsupportedOperationException(); | |||
} | |||
@@ -224,7 +224,7 @@ public class BranchPersisterImplTest { | |||
when(branch.getType()).thenReturn(type); | |||
when(branch.getName()).thenReturn(name); | |||
when(branch.isMain()).thenReturn(isMain); | |||
when(branch.getMergeBranchUuid()).thenReturn(mergeBranchUuid); | |||
when(branch.getReferenceBranchUuid()).thenReturn(mergeBranchUuid); | |||
when(branch.getTargetBranchName()).thenReturn(mergeBranchUuid); | |||
return branch; | |||
} |
@@ -35,14 +35,14 @@ import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.when; | |||
import static org.sonar.db.component.SnapshotTesting.newAnalysis; | |||
public class MergeAndTargetBranchComponentUuidsTest { | |||
public class ReferenceBranchComponentUuidsTest { | |||
@Rule | |||
public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule(); | |||
@Rule | |||
public DbTester db = DbTester.create(); | |||
private MergeAndTargetBranchComponentUuids underTest; | |||
private ReferenceBranchComponentUuids underTest; | |||
private Branch branch = mock(Branch.class); | |||
private ComponentDto branch1; | |||
@@ -57,7 +57,7 @@ public class MergeAndTargetBranchComponentUuidsTest { | |||
@Before | |||
public void setUp() { | |||
underTest = new MergeAndTargetBranchComponentUuids(analysisMetadataHolder, db.getDbClient()); | |||
underTest = new ReferenceBranchComponentUuids(analysisMetadataHolder, db.getDbClient()); | |||
project = mock(Project.class); | |||
analysisMetadataHolder.setProject(project); | |||
analysisMetadataHolder.setBranch(branch); | |||
@@ -76,71 +76,39 @@ public class MergeAndTargetBranchComponentUuidsTest { | |||
} | |||
@Test | |||
public void should_support_db_key_when_looking_for_merge_component() { | |||
when(branch.getMergeBranchUuid()).thenReturn(branch1.uuid()); | |||
public void should_support_db_key_when_looking_for_reference_component() { | |||
when(branch.getReferenceBranchUuid()).thenReturn(branch1.uuid()); | |||
when(branch.getType()).thenReturn(BranchType.PULL_REQUEST); | |||
when(branch.getTargetBranchName()).thenReturn("notAnalyzedBranch"); | |||
db.components().insertSnapshot(newAnalysis(branch1)); | |||
assertThat(underTest.getMergeBranchComponentUuid(pr1File.getDbKey())).isEqualTo(branch1File.uuid()); | |||
assertThat(underTest.getTargetBranchComponentUuid(pr1File.getDbKey())).isNull(); | |||
assertThat(underTest.hasMergeBranchAnalysis()).isTrue(); | |||
assertThat(underTest.hasTargetBranchAnalysis()).isFalse(); | |||
assertThat(underTest.areTargetAndMergeBranchesDifferent()).isTrue(); | |||
assertThat(underTest.getMergeBranchName()).isEqualTo("branch1"); | |||
assertThat(underTest.getComponentUuid(pr1File.getDbKey())).isEqualTo(branch1File.uuid()); | |||
assertThat(underTest.hasReferenceBranchAnalysis()).isTrue(); | |||
assertThat(underTest.getReferenceBranchName()).isEqualTo("branch1"); | |||
} | |||
@Test | |||
public void should_support_db_key_when_looking_for_target_component() { | |||
when(branch.getMergeBranchUuid()).thenReturn(branch1.uuid()); | |||
when(branch.getTargetBranchName()).thenReturn("branch2"); | |||
when(branch.getType()).thenReturn(BranchType.PULL_REQUEST); | |||
db.components().insertSnapshot(newAnalysis(branch1)); | |||
db.components().insertSnapshot(newAnalysis(branch2)); | |||
assertThat(underTest.getMergeBranchComponentUuid(pr1File.getDbKey())).isEqualTo(branch1File.uuid()); | |||
assertThat(underTest.getTargetBranchComponentUuid(pr1File.getDbKey())).isEqualTo(branch2File.uuid()); | |||
assertThat(underTest.hasMergeBranchAnalysis()).isTrue(); | |||
assertThat(underTest.hasTargetBranchAnalysis()).isTrue(); | |||
assertThat(underTest.areTargetAndMergeBranchesDifferent()).isTrue(); | |||
} | |||
@Test | |||
public void should_support_key_when_looking_for_merge_component() { | |||
when(branch.getMergeBranchUuid()).thenReturn(branch1.uuid()); | |||
public void should_support_key_when_looking_for_reference_component() { | |||
when(branch.getReferenceBranchUuid()).thenReturn(branch1.uuid()); | |||
when(branch.getType()).thenReturn(BranchType.PULL_REQUEST); | |||
when(branch.getTargetBranchName()).thenReturn("notAnalyzedBranch"); | |||
db.components().insertSnapshot(newAnalysis(branch1)); | |||
assertThat(underTest.getMergeBranchComponentUuid(pr1File.getKey())).isEqualTo(branch1File.uuid()); | |||
assertThat(underTest.getComponentUuid(pr1File.getKey())).isEqualTo(branch1File.uuid()); | |||
} | |||
@Test | |||
public void return_null_if_file_doesnt_exist() { | |||
when(branch.getMergeBranchUuid()).thenReturn(branch1.uuid()); | |||
when(branch.getReferenceBranchUuid()).thenReturn(branch1.uuid()); | |||
when(branch.getType()).thenReturn(BranchType.PULL_REQUEST); | |||
when(branch.getTargetBranchName()).thenReturn("notAnalyzedBranch"); | |||
db.components().insertSnapshot(newAnalysis(branch1)); | |||
assertThat(underTest.getMergeBranchComponentUuid("doesnt exist")).isNull(); | |||
assertThat(underTest.getComponentUuid("doesnt exist")).isNull(); | |||
} | |||
@Test | |||
public void skip_init_if_no_merge_branch_analysis() { | |||
when(branch.getMergeBranchUuid()).thenReturn(branch1.uuid()); | |||
public void skip_init_if_no_reference_branch_analysis() { | |||
when(branch.getReferenceBranchUuid()).thenReturn(branch1.uuid()); | |||
when(branch.getType()).thenReturn(BranchType.PULL_REQUEST); | |||
when(branch.getTargetBranchName()).thenReturn("notAnalyzedBranch"); | |||
assertThat(underTest.getMergeBranchComponentUuid(pr1File.getDbKey())).isNull(); | |||
} | |||
@Test | |||
public void should_skip_target_components_init_on_branches() { | |||
when(branch.getMergeBranchUuid()).thenReturn(branch1.uuid()); | |||
when(branch.getType()).thenReturn(BranchType.BRANCH); | |||
when(branch.getTargetBranchName()).thenThrow(new IllegalStateException("Unsupported on branches")); | |||
db.components().insertSnapshot(newAnalysis(branch1)); | |||
assertThat(underTest.getMergeBranchComponentUuid(branch2File.getDbKey())).isEqualTo(branch1File.uuid()); | |||
assertThat(underTest.getTargetBranchComponentUuid(branch2File.getDbKey())).isNull(); | |||
assertThat(underTest.hasMergeBranchAnalysis()).isTrue(); | |||
assertThat(underTest.hasTargetBranchAnalysis()).isFalse(); | |||
assertThat(underTest.areTargetAndMergeBranchesDifferent()).isTrue(); | |||
assertThat(underTest.getMergeBranchName()).isEqualTo("branch1"); | |||
assertThat(underTest.getComponentUuid(pr1File.getDbKey())).isNull(); | |||
} | |||
} |
@@ -21,7 +21,6 @@ package org.sonar.ce.task.projectanalysis.component; | |||
import javax.annotation.Nullable; | |||
import org.junit.Before; | |||
import org.junit.Ignore; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolderRule; | |||
@@ -49,133 +48,111 @@ public class SiblingComponentsWithOpenIssuesTest { | |||
private SiblingComponentsWithOpenIssues underTest; | |||
private ComponentDto long1; | |||
private ComponentDto fileWithNoIssuesOnLong1; | |||
private ComponentDto fileWithOneOpenIssueOnLong1Short1; | |||
private ComponentDto fileWithOneResolvedIssueOnLong1Short1; | |||
private ComponentDto fileWithOneOpenTwoResolvedIssuesOnLong1Short1; | |||
private ComponentDto fileXWithOneResolvedIssueOnLong1Short1; | |||
private ComponentDto fileXWithOneResolvedIssueOnLong1Short2; | |||
private ComponentDto branch1; | |||
private ComponentDto fileWithNoIssuesOnBranch1; | |||
private ComponentDto fileWithOneOpenIssueOnBranch1Pr1; | |||
private ComponentDto fileWithOneResolvedIssueOnBranch1Pr1; | |||
private ComponentDto fileWithOneOpenTwoResolvedIssuesOnBranch1Pr1; | |||
private ComponentDto fileXWithOneResolvedIssueOnBranch1Pr1; | |||
private ComponentDto fileXWithOneResolvedIssueOnBranch1Pr2; | |||
private ComponentDto long2; | |||
private ComponentDto fileWithOneOpenIssueOnLong2Short1; | |||
private ComponentDto fileWithOneResolvedIssueOnLong2Short1; | |||
private ComponentDto long1short1; | |||
private ComponentDto branch2; | |||
private ComponentDto fileWithOneOpenIssueOnBranch2Pr1; | |||
private ComponentDto fileWithOneResolvedIssueOnBranch2Pr1; | |||
private ComponentDto branch1pr1; | |||
@Before | |||
public void setUp() { | |||
ComponentDto project = db.components().insertMainBranch(); | |||
long1 = db.components().insertProjectBranch(project, b -> b.setKey("long1"), b -> b.setBranchType(BranchType.BRANCH)); | |||
long1short1 = db.components().insertProjectBranch(project, | |||
b -> b.setKey("long1short1"), | |||
b -> b.setBranchType(BranchType.SHORT), | |||
b -> b.setMergeBranchUuid(long1.uuid())); | |||
ComponentDto long1short2 = db.components().insertProjectBranch(project, | |||
b -> b.setKey("long1short2"), | |||
b -> b.setBranchType(BranchType.SHORT), | |||
b -> b.setMergeBranchUuid(long1.uuid())); | |||
branch1 = db.components().insertProjectBranch(project, b -> b.setKey("branch1"), b -> b.setBranchType(BranchType.BRANCH)); | |||
branch1pr1 = db.components().insertProjectBranch(project, | |||
b -> b.setKey("branch1pr1"), | |||
b -> b.setBranchType(BranchType.PULL_REQUEST), | |||
b -> b.setMergeBranchUuid(branch1.uuid())); | |||
ComponentDto branch1pr2 = db.components().insertProjectBranch(project, | |||
b -> b.setKey("branch1pr2"), | |||
b -> b.setBranchType(BranchType.PULL_REQUEST), | |||
b -> b.setMergeBranchUuid(branch1.uuid())); | |||
fileWithNoIssuesOnLong1 = db.components().insertComponent(ComponentTesting.newFileDto(long1, null)); | |||
fileWithNoIssuesOnBranch1 = db.components().insertComponent(ComponentTesting.newFileDto(branch1, null)); | |||
RuleDefinitionDto rule = db.rules().insert(); | |||
fileWithOneOpenIssueOnLong1Short1 = db.components().insertComponent(ComponentTesting.newFileDto(long1short1, null)); | |||
db.issues().insertIssue(IssueTesting.newIssue(rule, long1short1, fileWithOneOpenIssueOnLong1Short1)); | |||
fileWithOneOpenIssueOnBranch1Pr1 = db.components().insertComponent(ComponentTesting.newFileDto(branch1pr1, null)); | |||
db.issues().insertIssue(IssueTesting.newIssue(rule, branch1pr1, fileWithOneOpenIssueOnBranch1Pr1)); | |||
fileWithOneResolvedIssueOnLong1Short1 = db.components().insertComponent(ComponentTesting.newFileDto(long1short1, null)); | |||
db.issues().insertIssue(IssueTesting.newIssue(rule, long1short1, fileWithOneResolvedIssueOnLong1Short1).setStatus("RESOLVED")); | |||
fileWithOneResolvedIssueOnBranch1Pr1 = db.components().insertComponent(ComponentTesting.newFileDto(branch1pr1, null)); | |||
db.issues().insertIssue(IssueTesting.newIssue(rule, branch1pr1, fileWithOneResolvedIssueOnBranch1Pr1).setStatus("RESOLVED")); | |||
fileWithOneOpenTwoResolvedIssuesOnLong1Short1 = db.components().insertComponent(ComponentTesting.newFileDto(long1short1, null)); | |||
db.issues().insertIssue(IssueTesting.newIssue(rule, long1short1, fileWithOneOpenTwoResolvedIssuesOnLong1Short1)); | |||
db.issues().insertIssue(IssueTesting.newIssue(rule, long1short1, fileWithOneOpenTwoResolvedIssuesOnLong1Short1).setStatus("RESOLVED")); | |||
fileWithOneOpenTwoResolvedIssuesOnBranch1Pr1 = db.components().insertComponent(ComponentTesting.newFileDto(branch1pr1, null)); | |||
db.issues().insertIssue(IssueTesting.newIssue(rule, branch1pr1, fileWithOneOpenTwoResolvedIssuesOnBranch1Pr1)); | |||
db.issues().insertIssue(IssueTesting.newIssue(rule, branch1pr1, fileWithOneOpenTwoResolvedIssuesOnBranch1Pr1).setStatus("RESOLVED")); | |||
String fileKey = "file-x"; | |||
fileXWithOneResolvedIssueOnLong1Short1 = db.components().insertComponent(ComponentTesting.newFileDto(long1short1, null) | |||
.setDbKey(fileKey + ":BRANCH:long1short1")); | |||
db.issues().insertIssue(IssueTesting.newIssue(rule, long1short1, fileXWithOneResolvedIssueOnLong1Short1).setStatus("RESOLVED")); | |||
fileXWithOneResolvedIssueOnLong1Short2 = db.components().insertComponent(ComponentTesting.newFileDto(long1short2, null) | |||
.setDbKey(fileKey + ":BRANCH:long1short2")); | |||
db.issues().insertIssue(IssueTesting.newIssue(rule, long1short2, fileXWithOneResolvedIssueOnLong1Short2).setStatus("RESOLVED")); | |||
long2 = db.components().insertProjectBranch(project, b -> b.setKey("long2"), b -> b.setBranchType(BranchType.BRANCH)); | |||
ComponentDto long2short1 = db.components().insertProjectBranch(project, | |||
b -> b.setKey("long2short1"), | |||
b -> b.setBranchType(BranchType.SHORT), | |||
b -> b.setMergeBranchUuid(long2.uuid())); | |||
fileWithOneOpenIssueOnLong2Short1 = db.components().insertComponent(ComponentTesting.newFileDto(long2short1, null)); | |||
db.issues().insertIssue(IssueTesting.newIssue(rule, long2short1, fileWithOneOpenIssueOnLong2Short1)); | |||
fileWithOneResolvedIssueOnLong2Short1 = db.components().insertComponent(ComponentTesting.newFileDto(long2short1, null)); | |||
db.issues().insertIssue(IssueTesting.newIssue(rule, long2short1, fileWithOneResolvedIssueOnLong2Short1).setStatus("RESOLVED")); | |||
setRoot(long1); | |||
fileXWithOneResolvedIssueOnBranch1Pr1 = db.components().insertComponent(ComponentTesting.newFileDto(branch1pr1, null) | |||
.setDbKey(fileKey + ":BRANCH:branch1pr1")); | |||
db.issues().insertIssue(IssueTesting.newIssue(rule, branch1pr1, fileXWithOneResolvedIssueOnBranch1Pr1).setStatus("RESOLVED")); | |||
fileXWithOneResolvedIssueOnBranch1Pr2 = db.components().insertComponent(ComponentTesting.newFileDto(branch1pr2, null) | |||
.setDbKey(fileKey + ":BRANCH:branch1pr2")); | |||
db.issues().insertIssue(IssueTesting.newIssue(rule, branch1pr2, fileXWithOneResolvedIssueOnBranch1Pr2).setStatus("RESOLVED")); | |||
branch2 = db.components().insertProjectBranch(project, b -> b.setKey("branch2"), b -> b.setBranchType(BranchType.BRANCH)); | |||
ComponentDto branch2pr1 = db.components().insertProjectBranch(project, | |||
b -> b.setKey("branch2pr1"), | |||
b -> b.setBranchType(BranchType.PULL_REQUEST), | |||
b -> b.setMergeBranchUuid(branch2.uuid())); | |||
fileWithOneOpenIssueOnBranch2Pr1 = db.components().insertComponent(ComponentTesting.newFileDto(branch2pr1, null)); | |||
db.issues().insertIssue(IssueTesting.newIssue(rule, branch2pr1, fileWithOneOpenIssueOnBranch2Pr1)); | |||
fileWithOneResolvedIssueOnBranch2Pr1 = db.components().insertComponent(ComponentTesting.newFileDto(branch2pr1, null)); | |||
db.issues().insertIssue(IssueTesting.newIssue(rule, branch2pr1, fileWithOneResolvedIssueOnBranch2Pr1).setStatus("RESOLVED")); | |||
setRoot(branch1); | |||
underTest = new SiblingComponentsWithOpenIssues(treeRootHolder, metadataHolder, db.getDbClient()); | |||
} | |||
@Test | |||
public void should_find_sibling_components_with_open_issues_for_long1() { | |||
setRoot(long1); | |||
public void should_find_sibling_components_with_open_issues_for_branch1() { | |||
setRoot(branch1); | |||
setBranch(BranchType.BRANCH); | |||
assertThat(underTest.getUuids(fileWithNoIssuesOnLong1.getKey())).isEmpty(); | |||
assertThat(underTest.getUuids(fileWithOneOpenIssueOnLong1Short1.getKey())).containsOnly(fileWithOneOpenIssueOnLong1Short1.uuid()); | |||
assertThat(underTest.getUuids(fileWithOneResolvedIssueOnLong1Short1.getKey())).containsOnly(fileWithOneResolvedIssueOnLong1Short1.uuid()); | |||
assertThat(underTest.getUuids(fileWithOneOpenTwoResolvedIssuesOnLong1Short1.getKey())).containsOnly(fileWithOneOpenTwoResolvedIssuesOnLong1Short1.uuid()); | |||
assertThat(fileXWithOneResolvedIssueOnLong1Short1.getKey()).isEqualTo(fileXWithOneResolvedIssueOnLong1Short2.getKey()); | |||
assertThat(underTest.getUuids(fileXWithOneResolvedIssueOnLong1Short1.getKey())).containsOnly( | |||
fileXWithOneResolvedIssueOnLong1Short1.uuid(), | |||
fileXWithOneResolvedIssueOnLong1Short2.uuid()); | |||
} | |||
assertThat(underTest.getUuids(fileWithNoIssuesOnBranch1.getKey())).isEmpty(); | |||
assertThat(underTest.getUuids(fileWithOneOpenIssueOnBranch1Pr1.getKey())).containsOnly(fileWithOneOpenIssueOnBranch1Pr1.uuid()); | |||
assertThat(underTest.getUuids(fileWithOneResolvedIssueOnBranch1Pr1.getKey())).containsOnly(fileWithOneResolvedIssueOnBranch1Pr1.uuid()); | |||
assertThat(underTest.getUuids(fileWithOneOpenTwoResolvedIssuesOnBranch1Pr1.getKey())).containsOnly(fileWithOneOpenTwoResolvedIssuesOnBranch1Pr1.uuid()); | |||
@Test | |||
@Ignore | |||
public void should_find_sibling_components_with_open_issues_for_short1() { | |||
// TODO fix this test class | |||
setRoot(long1short1); | |||
setBranch(BranchType.SHORT, long1.uuid()); | |||
assertThat(underTest.getUuids(fileWithNoIssuesOnLong1.getKey())).isEmpty(); | |||
assertThat(underTest.getUuids(fileWithOneOpenIssueOnLong1Short1.getKey())).isEmpty(); | |||
assertThat(underTest.getUuids(fileWithOneResolvedIssueOnLong1Short1.getKey())).isEmpty(); | |||
assertThat(underTest.getUuids(fileWithOneOpenTwoResolvedIssuesOnLong1Short1.getKey())).isEmpty(); | |||
assertThat(underTest.getUuids(fileXWithOneResolvedIssueOnLong1Short1.getKey())).containsOnly( | |||
fileXWithOneResolvedIssueOnLong1Short2.uuid()); | |||
assertThat(fileXWithOneResolvedIssueOnBranch1Pr1.getKey()).isEqualTo(fileXWithOneResolvedIssueOnBranch1Pr2.getKey()); | |||
assertThat(underTest.getUuids(fileXWithOneResolvedIssueOnBranch1Pr1.getKey())).containsOnly( | |||
fileXWithOneResolvedIssueOnBranch1Pr1.uuid(), | |||
fileXWithOneResolvedIssueOnBranch1Pr2.uuid()); | |||
} | |||
@Test | |||
public void should_find_sibling_components_with_open_issues_for_long2() { | |||
setRoot(long2); | |||
setBranch(BranchType.BRANCH); | |||
public void should_find_sibling_components_with_open_issues_for_pr1() { | |||
setRoot(branch1pr1); | |||
setBranch(BranchType.PULL_REQUEST, branch1.uuid()); | |||
underTest = new SiblingComponentsWithOpenIssues(treeRootHolder, metadataHolder, db.getDbClient()); | |||
assertThat(underTest.getUuids(fileWithNoIssuesOnBranch1.getKey())).isEmpty(); | |||
assertThat(underTest.getUuids(fileWithOneOpenIssueOnBranch1Pr1.getKey())).isEmpty(); | |||
assertThat(underTest.getUuids(fileWithOneResolvedIssueOnBranch1Pr1.getKey())).isEmpty(); | |||
assertThat(underTest.getUuids(fileWithOneOpenTwoResolvedIssuesOnBranch1Pr1.getKey())).isEmpty(); | |||
assertThat(underTest.getUuids(fileWithOneResolvedIssueOnLong1Short1.getKey())).isEmpty(); | |||
assertThat(underTest.getUuids(fileWithOneResolvedIssueOnLong2Short1.getKey())).containsOnly(fileWithOneResolvedIssueOnLong2Short1.uuid()); | |||
assertThat(underTest.getUuids(fileWithOneOpenIssueOnLong2Short1.getKey())).containsOnly(fileWithOneOpenIssueOnLong2Short1.uuid()); | |||
assertThat(underTest.getUuids(fileXWithOneResolvedIssueOnBranch1Pr1.getKey())).containsOnly( | |||
fileXWithOneResolvedIssueOnBranch1Pr2.uuid()); | |||
} | |||
@Test | |||
public void should_find_sibling_components_with_open_issues_from_short() { | |||
ComponentDto project = db.components().insertMainBranch(); | |||
setRoot(project); | |||
public void should_find_sibling_components_with_open_issues_for_branch2() { | |||
setRoot(branch2); | |||
setBranch(BranchType.BRANCH); | |||
ComponentDto branch = db.components().insertProjectBranch(project, | |||
b -> b.setBranchType(BranchType.SHORT), | |||
b -> b.setMergeBranchUuid(project.uuid())); | |||
RuleDefinitionDto rule = db.rules().insert(); | |||
ComponentDto fileWithResolvedIssueOnShort = db.components().insertComponent(ComponentTesting.newFileDto(branch, null)); | |||
db.issues().insertIssue(IssueTesting.newIssue(rule, branch, fileWithResolvedIssueOnShort).setStatus("RESOLVED")); | |||
underTest = new SiblingComponentsWithOpenIssues(treeRootHolder, metadataHolder, db.getDbClient()); | |||
assertThat(underTest.getUuids(fileWithResolvedIssueOnShort.getKey())).hasSize(1); | |||
assertThat(underTest.getUuids(fileWithOneResolvedIssueOnBranch1Pr1.getKey())).isEmpty(); | |||
assertThat(underTest.getUuids(fileWithOneResolvedIssueOnBranch2Pr1.getKey())).containsOnly(fileWithOneResolvedIssueOnBranch2Pr1.uuid()); | |||
assertThat(underTest.getUuids(fileWithOneOpenIssueOnBranch2Pr1.getKey())).containsOnly(fileWithOneOpenIssueOnBranch2Pr1.uuid()); | |||
} | |||
@Test | |||
@@ -199,23 +176,23 @@ public class SiblingComponentsWithOpenIssuesTest { | |||
} | |||
@Test | |||
public void should_not_find_sibling_components_on_derived_long() { | |||
public void should_not_find_sibling_components_on_derived_branch() { | |||
ComponentDto project = db.components().insertMainBranch(); | |||
setRoot(project); | |||
setBranch(BranchType.BRANCH); | |||
ComponentDto derivedLongBranch = db.components().insertProjectBranch(project, | |||
ComponentDto derivedBranch = db.components().insertProjectBranch(project, | |||
b -> b.setBranchType(BranchType.BRANCH), | |||
b -> b.setMergeBranchUuid(project.uuid())); | |||
RuleDefinitionDto rule = db.rules().insert(); | |||
ComponentDto fileWithResolvedIssueOnDerivedLongBranch = db.components().insertComponent(ComponentTesting.newFileDto(derivedLongBranch, null)); | |||
db.issues().insertIssue(IssueTesting.newIssue(rule, derivedLongBranch, fileWithResolvedIssueOnDerivedLongBranch).setStatus("RESOLVED")); | |||
ComponentDto fileWithResolvedIssueOnDerivedBranch = db.components().insertComponent(ComponentTesting.newFileDto(derivedBranch, null)); | |||
db.issues().insertIssue(IssueTesting.newIssue(rule, derivedBranch, fileWithResolvedIssueOnDerivedBranch).setStatus("RESOLVED")); | |||
underTest = new SiblingComponentsWithOpenIssues(treeRootHolder, metadataHolder, db.getDbClient()); | |||
assertThat(underTest.getUuids(fileWithResolvedIssueOnDerivedLongBranch.getKey())).isEmpty(); | |||
assertThat(underTest.getUuids(fileWithResolvedIssueOnDerivedBranch.getKey())).isEmpty(); | |||
} | |||
private void setRoot(ComponentDto componentDto) { | |||
@@ -231,7 +208,7 @@ public class SiblingComponentsWithOpenIssuesTest { | |||
private void setBranch(BranchType currentBranchType, @Nullable String mergeBranchUuid) { | |||
Branch branch = mock(Branch.class); | |||
when(branch.getType()).thenReturn(currentBranchType); | |||
when(branch.getMergeBranchUuid()).thenReturn(mergeBranchUuid); | |||
when(branch.getReferenceBranchUuid()).thenReturn(mergeBranchUuid); | |||
metadataHolder.setBranch(branch); | |||
} | |||
} |
@@ -20,7 +20,6 @@ | |||
package org.sonar.ce.task.projectanalysis.issue; | |||
import com.google.common.base.Optional; | |||
import java.util.Collections; | |||
import java.util.List; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
@@ -36,7 +35,7 @@ import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder; | |||
import org.sonar.ce.task.projectanalysis.analysis.Branch; | |||
import org.sonar.ce.task.projectanalysis.batch.BatchReportReaderRule; | |||
import org.sonar.ce.task.projectanalysis.component.Component; | |||
import org.sonar.ce.task.projectanalysis.component.MergeAndTargetBranchComponentUuids; | |||
import org.sonar.ce.task.projectanalysis.component.ReferenceBranchComponentUuids; | |||
import org.sonar.ce.task.projectanalysis.component.ReportComponent; | |||
import org.sonar.ce.task.projectanalysis.component.ReportModulesPath; | |||
import org.sonar.ce.task.projectanalysis.component.TreeRootHolderRule; | |||
@@ -67,6 +66,7 @@ import org.sonar.server.issue.IssueFieldsSetter; | |||
import static com.google.common.collect.Lists.newArrayList; | |||
import static java.util.Arrays.asList; | |||
import static java.util.Collections.singletonList; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.ArgumentMatchers.any; | |||
import static org.mockito.ArgumentMatchers.eq; | |||
@@ -116,18 +116,19 @@ public class IntegrateIssuesVisitorTest { | |||
private MovedFilesRepository movedFilesRepository = mock(MovedFilesRepository.class); | |||
private IssueLifecycle issueLifecycle = mock(IssueLifecycle.class); | |||
private IssueVisitor issueVisitor = mock(IssueVisitor.class); | |||
private MergeAndTargetBranchComponentUuids mergeBranchComponentsUuids = mock(MergeAndTargetBranchComponentUuids.class); | |||
private ReferenceBranchComponentUuids mergeBranchComponentsUuids = mock(ReferenceBranchComponentUuids.class); | |||
private SiblingsIssueMerger issueStatusCopier = mock(SiblingsIssueMerger.class); | |||
private MergeAndTargetBranchComponentUuids mergeAndTargetBranchComponentUuids = mock(MergeAndTargetBranchComponentUuids.class); | |||
private ReferenceBranchComponentUuids referenceBranchComponentUuids = mock(ReferenceBranchComponentUuids.class); | |||
private SourceLinesHashRepository sourceLinesHash = mock(SourceLinesHashRepository.class); | |||
private NewLinesRepository newLinesRepository = mock(NewLinesRepository.class); | |||
private ArgumentCaptor<DefaultIssue> defaultIssueCaptor; | |||
private ComponentIssuesLoader issuesLoader = new ComponentIssuesLoader(dbTester.getDbClient(), ruleRepositoryRule, activeRulesHolderRule, new MapSettings().asConfig(), System2.INSTANCE); | |||
private ComponentIssuesLoader issuesLoader = new ComponentIssuesLoader(dbTester.getDbClient(), ruleRepositoryRule, activeRulesHolderRule, new MapSettings().asConfig(), | |||
System2.INSTANCE); | |||
private IssueTrackingDelegator trackingDelegator; | |||
private TrackerExecution tracker; | |||
private PullRequestTrackerExecution shortBranchTracker; | |||
private PullRequestTrackerExecution prBranchTracker; | |||
private ReferenceBranchTrackerExecution mergeBranchTracker; | |||
private ActiveRulesHolder activeRulesHolder = new AlwaysActiveRulesHolderImpl(); | |||
private IssueCache issueCache; | |||
@@ -144,18 +145,19 @@ public class IntegrateIssuesVisitorTest { | |||
DbClient dbClient = dbTester.getDbClient(); | |||
TrackerRawInputFactory rawInputFactory = new TrackerRawInputFactory(treeRootHolder, reportReader, sourceLinesHash, new CommonRuleEngineImpl(), | |||
issueFilter, ruleRepositoryRule, activeRulesHolder); | |||
TrackerBaseInputFactory baseInputFactory = new TrackerBaseInputFactory(issuesLoader, dbClient, movedFilesRepository, mock(ReportModulesPath.class), analysisMetadataHolder, new IssueFieldsSetter(), mock(ComponentsWithUnprocessedIssues.class)); | |||
TrackerMergeOrTargetBranchInputFactory mergeInputFactory = new TrackerMergeOrTargetBranchInputFactory(issuesLoader, mergeBranchComponentsUuids, dbClient); | |||
TrackerBaseInputFactory baseInputFactory = new TrackerBaseInputFactory(issuesLoader, dbClient, movedFilesRepository, mock(ReportModulesPath.class), analysisMetadataHolder, | |||
new IssueFieldsSetter(), mock(ComponentsWithUnprocessedIssues.class)); | |||
TrackerReferenceBranchInputFactory mergeInputFactory = new TrackerReferenceBranchInputFactory(issuesLoader, mergeBranchComponentsUuids, dbClient); | |||
ClosedIssuesInputFactory closedIssuesInputFactory = new ClosedIssuesInputFactory(issuesLoader, dbClient, movedFilesRepository); | |||
tracker = new TrackerExecution(baseInputFactory, rawInputFactory, closedIssuesInputFactory, new Tracker<>(), issuesLoader, analysisMetadataHolder); | |||
shortBranchTracker = new PullRequestTrackerExecution(baseInputFactory, rawInputFactory, new Tracker<>(), newLinesRepository); | |||
prBranchTracker = new PullRequestTrackerExecution(baseInputFactory, rawInputFactory, new Tracker<>(), newLinesRepository); | |||
mergeBranchTracker = new ReferenceBranchTrackerExecution(rawInputFactory, mergeInputFactory, new Tracker<>()); | |||
trackingDelegator = new IssueTrackingDelegator(shortBranchTracker, mergeBranchTracker, tracker, analysisMetadataHolder); | |||
trackingDelegator = new IssueTrackingDelegator(prBranchTracker, mergeBranchTracker, tracker, analysisMetadataHolder); | |||
treeRootHolder.setRoot(PROJECT); | |||
issueCache = new IssueCache(temp.newFile(), System2.INSTANCE); | |||
when(issueFilter.accept(any(DefaultIssue.class), eq(FILE))).thenReturn(true); | |||
underTest = new IntegrateIssuesVisitor(issueCache, issueLifecycle, issueVisitors, trackingDelegator, issueStatusCopier, mergeAndTargetBranchComponentUuids); | |||
underTest = new IntegrateIssuesVisitor(issueCache, issueLifecycle, issueVisitors, trackingDelegator, issueStatusCopier, referenceBranchComponentUuids); | |||
} | |||
@Test | |||
@@ -176,7 +178,7 @@ public class IntegrateIssuesVisitorTest { | |||
DefaultIssue capturedIssue = defaultIssueCaptor.getValue(); | |||
assertThat(capturedIssue.ruleKey().rule()).isEqualTo("S001"); | |||
verify(issueStatusCopier).tryMerge(FILE, Collections.singletonList(capturedIssue)); | |||
verify(issueStatusCopier).tryMerge(FILE, singletonList(capturedIssue)); | |||
verify(issueLifecycle).doAutomaticTransition(capturedIssue); | |||
@@ -260,10 +262,10 @@ public class IntegrateIssuesVisitorTest { | |||
} | |||
@Test | |||
public void copy_issues_when_creating_new_long_living_branch() { | |||
public void copy_issues_when_creating_new_non_main_branch() { | |||
when(mergeBranchComponentsUuids.getMergeBranchComponentUuid(FILE_KEY)).thenReturn(FILE_UUID_ON_BRANCH); | |||
when(mergeAndTargetBranchComponentUuids.getMergeBranchName()).thenReturn("master"); | |||
when(mergeBranchComponentsUuids.getComponentUuid(FILE_KEY)).thenReturn(FILE_UUID_ON_BRANCH); | |||
when(referenceBranchComponentUuids.getReferenceBranchName()).thenReturn("master"); | |||
when(analysisMetadataHolder.isBranch()).thenReturn(true); | |||
when(analysisMetadataHolder.isFirstAnalysis()).thenReturn(true); | |||
@@ -283,14 +285,14 @@ public class IntegrateIssuesVisitorTest { | |||
.setRuleKey(ruleKey.rule()) | |||
.setSeverity(Constants.Severity.BLOCKER) | |||
.build(); | |||
reportReader.putIssues(FILE_REF, asList(reportIssue)); | |||
reportReader.putIssues(FILE_REF, singletonList(reportIssue)); | |||
fileSourceRepository.addLine(FILE_REF, "line1"); | |||
underTest.visitAny(FILE); | |||
ArgumentCaptor<DefaultIssue> rawIssueCaptor = ArgumentCaptor.forClass(DefaultIssue.class); | |||
ArgumentCaptor<DefaultIssue> baseIssueCaptor = ArgumentCaptor.forClass(DefaultIssue.class); | |||
verify(issueLifecycle).copyExistingOpenIssueFromLongLivingBranch(rawIssueCaptor.capture(), baseIssueCaptor.capture(), eq("master")); | |||
verify(issueLifecycle).copyExistingOpenIssueFromBranch(rawIssueCaptor.capture(), baseIssueCaptor.capture(), eq("master")); | |||
assertThat(rawIssueCaptor.getValue().severity()).isEqualTo(Severity.BLOCKER); | |||
assertThat(baseIssueCaptor.getValue().severity()).isEqualTo(Severity.MAJOR); | |||
@@ -31,8 +31,6 @@ import org.sonar.core.issue.DefaultIssue; | |||
import org.sonar.core.issue.DefaultIssueComment; | |||
import org.sonar.core.issue.FieldDiffs; | |||
import org.sonar.core.issue.IssueChangeContext; | |||
import org.sonar.db.component.BranchType; | |||
import org.sonar.db.component.KeyType; | |||
import org.sonar.db.protobuf.DbCommons; | |||
import org.sonar.db.protobuf.DbIssues; | |||
import org.sonar.server.issue.IssueFieldsSetter; | |||
@@ -58,27 +56,20 @@ import static org.sonar.api.utils.DateUtils.parseDate; | |||
import static org.sonar.db.rule.RuleTesting.XOO_X1; | |||
public class IssueLifecycleTest { | |||
private static final Date DEFAULT_DATE = new Date(); | |||
private static final Duration DEFAULT_DURATION = Duration.create(10); | |||
DumbRule rule = new DumbRule(XOO_X1); | |||
private DumbRule rule = new DumbRule(XOO_X1); | |||
@org.junit.Rule | |||
@Rule | |||
public RuleRepositoryRule ruleRepository = new RuleRepositoryRule().add(rule); | |||
@Rule | |||
public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule(); | |||
private IssueChangeContext issueChangeContext = IssueChangeContext.createUser(DEFAULT_DATE, "default_user_uuid"); | |||
private IssueWorkflow workflow = mock(IssueWorkflow.class); | |||
private IssueFieldsSetter updater = mock(IssueFieldsSetter.class); | |||
private DebtCalculator debtCalculator = mock(DebtCalculator.class); | |||
private IssueLifecycle underTest = new IssueLifecycle(analysisMetadataHolder, issueChangeContext, workflow, updater, debtCalculator, ruleRepository); | |||
@Test | |||
@@ -120,114 +111,7 @@ public class IssueLifecycleTest { | |||
} | |||
@Test | |||
public void mergeIssueFromShortLivingBranchIntoLLB() { | |||
DefaultIssue raw = new DefaultIssue() | |||
.setKey("raw"); | |||
DefaultIssue fromShort = new DefaultIssue() | |||
.setKey("short"); | |||
fromShort.setResolution("resolution"); | |||
fromShort.setStatus("status"); | |||
Date commentDate = new Date(); | |||
fromShort.addComment(new DefaultIssueComment() | |||
.setIssueKey("short") | |||
.setCreatedAt(commentDate) | |||
.setUserUuid("user_uuid") | |||
.setMarkdownText("A comment")); | |||
Date diffDate = new Date(); | |||
// file diff alone | |||
fromShort.addChange(new FieldDiffs() | |||
.setCreationDate(diffDate) | |||
.setIssueKey("short") | |||
.setUserUuid("user_uuid") | |||
.setDiff("file", "uuidA1", "uuidB1")); | |||
// file diff with another field | |||
fromShort.addChange(new FieldDiffs() | |||
.setCreationDate(diffDate) | |||
.setIssueKey("short") | |||
.setUserUuid("user_uuid") | |||
.setDiff("severity", "MINOR", "MAJOR") | |||
.setDiff("file", "uuidA2", "uuidB2")); | |||
Branch branch = mock(Branch.class); | |||
when(branch.getName()).thenReturn("master"); | |||
analysisMetadataHolder.setBranch(branch); | |||
underTest.mergeConfirmedOrResolvedFromShortLivingBranchOrPr(raw, fromShort, KeyType.BRANCH, "feature/foo"); | |||
assertThat(raw.resolution()).isEqualTo("resolution"); | |||
assertThat(raw.status()).isEqualTo("status"); | |||
assertThat(raw.defaultIssueComments()) | |||
.extracting(DefaultIssueComment::issueKey, DefaultIssueComment::createdAt, DefaultIssueComment::userUuid, DefaultIssueComment::markdownText) | |||
.containsOnly(tuple("raw", commentDate, "user_uuid", "A comment")); | |||
assertThat(raw.changes()).hasSize(2); | |||
assertThat(raw.changes().get(0).creationDate()).isEqualTo(diffDate); | |||
assertThat(raw.changes().get(0).userUuid()).isEqualTo("user_uuid"); | |||
assertThat(raw.changes().get(0).issueKey()).isEqualTo("raw"); | |||
assertThat(raw.changes().get(0).diffs()).containsOnlyKeys("severity"); | |||
assertThat(raw.changes().get(1).userUuid()).isEqualTo("default_user_uuid"); | |||
assertThat(raw.changes().get(1).diffs()).containsOnlyKeys(IssueFieldsSetter.FROM_SHORT_BRANCH); | |||
assertThat(raw.changes().get(1).get(IssueFieldsSetter.FROM_SHORT_BRANCH).oldValue()).isEqualTo("feature/foo"); | |||
assertThat(raw.changes().get(1).get(IssueFieldsSetter.FROM_SHORT_BRANCH).newValue()).isEqualTo("master"); | |||
} | |||
@Test | |||
public void mergeIssueFromShortLivingBranchIntoPR() { | |||
DefaultIssue raw = new DefaultIssue() | |||
.setKey("raw"); | |||
DefaultIssue fromShort = new DefaultIssue() | |||
.setKey("short"); | |||
fromShort.setResolution("resolution"); | |||
fromShort.setStatus("status"); | |||
Date commentDate = new Date(); | |||
fromShort.addComment(new DefaultIssueComment() | |||
.setIssueKey("short") | |||
.setCreatedAt(commentDate) | |||
.setUserUuid("user_uuid") | |||
.setMarkdownText("A comment")); | |||
Date diffDate = new Date(); | |||
// file diff alone | |||
fromShort.addChange(new FieldDiffs() | |||
.setCreationDate(diffDate) | |||
.setIssueKey("short") | |||
.setUserUuid("user_uuid") | |||
.setDiff("file", "uuidA1", "uuidB1")); | |||
// file diff with another field | |||
fromShort.addChange(new FieldDiffs() | |||
.setCreationDate(diffDate) | |||
.setIssueKey("short") | |||
.setUserUuid("user_uuid") | |||
.setDiff("severity", "MINOR", "MAJOR") | |||
.setDiff("file", "uuidA2", "uuidB2")); | |||
Branch branch = mock(Branch.class); | |||
when(branch.getType()).thenReturn(BranchType.PULL_REQUEST); | |||
analysisMetadataHolder.setBranch(branch); | |||
analysisMetadataHolder.setPullRequestKey("3"); | |||
underTest.mergeConfirmedOrResolvedFromShortLivingBranchOrPr(raw, fromShort, KeyType.BRANCH, "feature/foo"); | |||
assertThat(raw.resolution()).isEqualTo("resolution"); | |||
assertThat(raw.status()).isEqualTo("status"); | |||
assertThat(raw.defaultIssueComments()) | |||
.extracting(DefaultIssueComment::issueKey, DefaultIssueComment::createdAt, DefaultIssueComment::userUuid, DefaultIssueComment::markdownText) | |||
.containsOnly(tuple("raw", commentDate, "user_uuid", "A comment")); | |||
assertThat(raw.changes()).hasSize(2); | |||
assertThat(raw.changes().get(0).creationDate()).isEqualTo(diffDate); | |||
assertThat(raw.changes().get(0).userUuid()).isEqualTo("user_uuid"); | |||
assertThat(raw.changes().get(0).issueKey()).isEqualTo("raw"); | |||
assertThat(raw.changes().get(0).diffs()).containsOnlyKeys("severity"); | |||
assertThat(raw.changes().get(1).userUuid()).isEqualTo("default_user_uuid"); | |||
assertThat(raw.changes().get(1).diffs()).containsOnlyKeys(IssueFieldsSetter.FROM_SHORT_BRANCH); | |||
assertThat(raw.changes().get(1).get(IssueFieldsSetter.FROM_SHORT_BRANCH).oldValue()).isEqualTo("feature/foo"); | |||
assertThat(raw.changes().get(1).get(IssueFieldsSetter.FROM_SHORT_BRANCH).newValue()).isEqualTo("#3"); | |||
} | |||
@Test | |||
public void mergeIssueFromPRIntoLLB() { | |||
public void mergeIssueFromPRIntoBranch() { | |||
DefaultIssue raw = new DefaultIssue() | |||
.setKey("raw"); | |||
DefaultIssue fromShort = new DefaultIssue() | |||
@@ -261,7 +145,7 @@ public class IssueLifecycleTest { | |||
when(branch.getName()).thenReturn("master"); | |||
analysisMetadataHolder.setBranch(branch); | |||
underTest.mergeConfirmedOrResolvedFromShortLivingBranchOrPr(raw, fromShort, KeyType.PULL_REQUEST, "1"); | |||
underTest.mergeConfirmedOrResolvedFromPr(raw, fromShort, "2"); | |||
assertThat(raw.resolution()).isEqualTo("resolution"); | |||
assertThat(raw.status()).isEqualTo("status"); | |||
@@ -274,9 +158,9 @@ public class IssueLifecycleTest { | |||
assertThat(raw.changes().get(0).issueKey()).isEqualTo("raw"); | |||
assertThat(raw.changes().get(0).diffs()).containsOnlyKeys("severity"); | |||
assertThat(raw.changes().get(1).userUuid()).isEqualTo("default_user_uuid"); | |||
assertThat(raw.changes().get(1).diffs()).containsOnlyKeys(IssueFieldsSetter.FROM_SHORT_BRANCH); | |||
assertThat(raw.changes().get(1).get(IssueFieldsSetter.FROM_SHORT_BRANCH).oldValue()).isEqualTo("#1"); | |||
assertThat(raw.changes().get(1).get(IssueFieldsSetter.FROM_SHORT_BRANCH).newValue()).isEqualTo("master"); | |||
assertThat(raw.changes().get(1).diffs()).containsOnlyKeys(IssueFieldsSetter.FROM_BRANCH); | |||
assertThat(raw.changes().get(1).get(IssueFieldsSetter.FROM_BRANCH).oldValue()).isEqualTo("#2"); | |||
assertThat(raw.changes().get(1).get(IssueFieldsSetter.FROM_BRANCH).newValue()).isEqualTo("master"); | |||
} | |||
@Test | |||
@@ -320,7 +204,7 @@ public class IssueLifecycleTest { | |||
when(branch.getName()).thenReturn("release-2.x"); | |||
analysisMetadataHolder.setBranch(branch); | |||
underTest.copyExistingOpenIssueFromLongLivingBranch(raw, base, "master"); | |||
underTest.copyExistingOpenIssueFromBranch(raw, base, "master"); | |||
assertThat(raw.isNew()).isFalse(); | |||
assertThat(raw.isCopied()).isTrue(); | |||
@@ -337,8 +221,8 @@ public class IssueLifecycleTest { | |||
assertThat(raw.effort()).isEqualTo(DEFAULT_DURATION); | |||
assertThat(raw.isOnDisabledRule()).isTrue(); | |||
assertThat(raw.selectedAt()).isEqualTo(1000L); | |||
assertThat(raw.changes().get(0).get(IssueFieldsSetter.FROM_LONG_BRANCH).oldValue()).isEqualTo("master"); | |||
assertThat(raw.changes().get(0).get(IssueFieldsSetter.FROM_LONG_BRANCH).newValue()).isEqualTo("release-2.x"); | |||
assertThat(raw.changes().get(0).get(IssueFieldsSetter.FROM_BRANCH).oldValue()).isEqualTo("master"); | |||
assertThat(raw.changes().get(0).get(IssueFieldsSetter.FROM_BRANCH).newValue()).isEqualTo("release-2.x"); | |||
verifyZeroInteractions(updater); | |||
} |
@@ -37,7 +37,7 @@ import static org.mockito.Mockito.when; | |||
public class IssueTrackingDelegatorTest { | |||
@Mock | |||
private PullRequestTrackerExecution shortBranchTracker; | |||
private PullRequestTrackerExecution prBranchTracker; | |||
@Mock | |||
private ReferenceBranchTrackerExecution mergeBranchTracker; | |||
@Mock | |||
@@ -54,10 +54,10 @@ public class IssueTrackingDelegatorTest { | |||
@Before | |||
public void setUp() { | |||
MockitoAnnotations.initMocks(this); | |||
underTest = new IssueTrackingDelegator(shortBranchTracker, mergeBranchTracker, tracker, analysisMetadataHolder); | |||
underTest = new IssueTrackingDelegator(prBranchTracker, mergeBranchTracker, tracker, analysisMetadataHolder); | |||
when(tracker.track(component)).thenReturn(trackingResult); | |||
when(mergeBranchTracker.track(component)).thenReturn(trackingResult); | |||
when(shortBranchTracker.track(component)).thenReturn(trackingResult); | |||
when(prBranchTracker.track(component)).thenReturn(trackingResult); | |||
} | |||
@Test | |||
@@ -67,7 +67,7 @@ public class IssueTrackingDelegatorTest { | |||
underTest.track(component); | |||
verify(tracker).track(component); | |||
verifyZeroInteractions(shortBranchTracker); | |||
verifyZeroInteractions(prBranchTracker); | |||
verifyZeroInteractions(mergeBranchTracker); | |||
} | |||
@@ -83,7 +83,7 @@ public class IssueTrackingDelegatorTest { | |||
verify(mergeBranchTracker).track(component); | |||
verifyZeroInteractions(tracker); | |||
verifyZeroInteractions(shortBranchTracker); | |||
verifyZeroInteractions(prBranchTracker); | |||
} | |||
@@ -96,7 +96,7 @@ public class IssueTrackingDelegatorTest { | |||
underTest.track(component); | |||
verify(shortBranchTracker).track(component); | |||
verify(prBranchTracker).track(component); | |||
verifyZeroInteractions(tracker); | |||
verifyZeroInteractions(mergeBranchTracker); | |||
} |
@@ -37,7 +37,7 @@ public class ReferenceBranchTrackerExecutionTest { | |||
@Mock | |||
private TrackerRawInputFactory rawInputFactory; | |||
@Mock | |||
private TrackerMergeOrTargetBranchInputFactory mergeInputFactory; | |||
private TrackerReferenceBranchInputFactory mergeInputFactory; | |||
@Mock | |||
private Tracker<DefaultIssue, DefaultIssue> tracker; | |||
@Mock | |||
@@ -57,7 +57,7 @@ public class ReferenceBranchTrackerExecutionTest { | |||
Input<DefaultIssue> mergeInput = mock(Input.class); | |||
NonClosedTracking<DefaultIssue, DefaultIssue> result = mock(NonClosedTracking.class); | |||
when(rawInputFactory.create(component)).thenReturn(rawInput); | |||
when(mergeInputFactory.createForMergeBranch(component)).thenReturn(mergeInput); | |||
when(mergeInputFactory.create(component)).thenReturn(mergeInput); | |||
when(tracker.trackNonClosed(rawInput, mergeInput)).thenReturn(result); | |||
assertThat(underTest.track(component)).isEqualTo(result); |
@@ -45,7 +45,6 @@ import org.sonar.db.DbClient; | |||
import org.sonar.db.DbTester; | |||
import org.sonar.db.component.BranchType; | |||
import org.sonar.db.component.ComponentDto; | |||
import org.sonar.db.component.KeyType; | |||
import org.sonar.db.issue.IssueDto; | |||
import org.sonar.db.issue.IssueTesting; | |||
import org.sonar.db.rule.RuleDefinitionDto; | |||
@@ -112,19 +111,19 @@ public class SiblingsIssueMergerTest { | |||
issueLifecycle); | |||
projectDto = db.components().insertMainBranch(p -> p.setDbKey(PROJECT_KEY).setUuid(PROJECT_UUID)); | |||
branch1Dto = db.components().insertProjectBranch(projectDto, b -> b.setKey("myBranch1") | |||
.setBranchType(BranchType.SHORT) | |||
.setBranchType(BranchType.PULL_REQUEST) | |||
.setMergeBranchUuid(projectDto.uuid())); | |||
branch2Dto = db.components().insertProjectBranch(projectDto, b -> b.setKey("myBranch2") | |||
.setBranchType(BranchType.SHORT) | |||
.setBranchType(BranchType.PULL_REQUEST) | |||
.setMergeBranchUuid(projectDto.uuid())); | |||
branch3Dto = db.components().insertProjectBranch(projectDto, b -> b.setKey("myBranch3") | |||
.setBranchType(BranchType.SHORT) | |||
.setBranchType(BranchType.PULL_REQUEST) | |||
.setMergeBranchUuid(projectDto.uuid())); | |||
fileOnBranch1Dto = db.components().insertComponent(newFileDto(branch1Dto).setDbKey(FILE_1_KEY + ":BRANCH:myBranch1")); | |||
fileOnBranch2Dto = db.components().insertComponent(newFileDto(branch2Dto).setDbKey(FILE_1_KEY + ":BRANCH:myBranch2")); | |||
fileOnBranch3Dto = db.components().insertComponent(newFileDto(branch3Dto).setDbKey(FILE_1_KEY + ":BRANCH:myBranch3")); | |||
fileOnBranch1Dto = db.components().insertComponent(newFileDto(branch1Dto).setDbKey(FILE_1_KEY + ":PULL_REQUEST:myBranch1")); | |||
fileOnBranch2Dto = db.components().insertComponent(newFileDto(branch2Dto).setDbKey(FILE_1_KEY + ":PULL_REQUEST:myBranch2")); | |||
fileOnBranch3Dto = db.components().insertComponent(newFileDto(branch3Dto).setDbKey(FILE_1_KEY + ":PULL_REQUEST:myBranch3")); | |||
rule = db.rules().insert(); | |||
when(branch.getMergeBranchUuid()).thenReturn(projectDto.uuid()); | |||
when(branch.getReferenceBranchUuid()).thenReturn(projectDto.uuid()); | |||
metadataHolder.setBranch(branch); | |||
} | |||
@@ -152,7 +151,7 @@ public class SiblingsIssueMergerTest { | |||
copier.tryMerge(FILE_1, Collections.singleton(newIssue)); | |||
ArgumentCaptor<DefaultIssue> issueToMerge = ArgumentCaptor.forClass(DefaultIssue.class); | |||
verify(issueLifecycle).mergeConfirmedOrResolvedFromShortLivingBranchOrPr(eq(newIssue), issueToMerge.capture(), eq(KeyType.BRANCH), eq("myBranch1")); | |||
verify(issueLifecycle).mergeConfirmedOrResolvedFromPr(eq(newIssue), issueToMerge.capture(), eq("myBranch1")); | |||
assertThat(issueToMerge.getValue().key()).isEqualTo("issue1"); | |||
} | |||
@@ -171,7 +170,7 @@ public class SiblingsIssueMergerTest { | |||
copier.tryMerge(FILE_1, Collections.singleton(newIssue)); | |||
ArgumentCaptor<DefaultIssue> issueToMerge = ArgumentCaptor.forClass(DefaultIssue.class); | |||
verify(issueLifecycle).mergeConfirmedOrResolvedFromShortLivingBranchOrPr(eq(newIssue), issueToMerge.capture(), eq(KeyType.BRANCH), eq("myBranch1")); | |||
verify(issueLifecycle).mergeConfirmedOrResolvedFromPr(eq(newIssue), issueToMerge.capture(), eq("myBranch1")); | |||
assertThat(issueToMerge.getValue().key()).isEqualTo("issue1"); | |||
} | |||
@@ -188,7 +187,7 @@ public class SiblingsIssueMergerTest { | |||
copier.tryMerge(FILE_1, Collections.singleton(newIssue)); | |||
ArgumentCaptor<DefaultIssue> issueToMerge = ArgumentCaptor.forClass(DefaultIssue.class); | |||
verify(issueLifecycle).mergeConfirmedOrResolvedFromShortLivingBranchOrPr(eq(newIssue), issueToMerge.capture(), eq(KeyType.BRANCH), eq("myBranch2")); | |||
verify(issueLifecycle).mergeConfirmedOrResolvedFromPr(eq(newIssue), issueToMerge.capture(), eq("myBranch2")); | |||
assertThat(issueToMerge.getValue().key()).isEqualTo("issue"); | |||
assertThat(issueToMerge.getValue().defaultIssueComments()).isNotEmpty(); |
@@ -0,0 +1,81 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2019 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program 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. | |||
* | |||
* This program 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.ce.task.projectanalysis.issue; | |||
import java.util.Collections; | |||
import org.junit.Before; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.sonar.ce.task.projectanalysis.component.Component; | |||
import org.sonar.ce.task.projectanalysis.component.ReferenceBranchComponentUuids; | |||
import org.sonar.core.issue.DefaultIssue; | |||
import org.sonar.core.issue.tracking.Input; | |||
import org.sonar.db.DbTester; | |||
import org.sonar.db.component.ComponentDto; | |||
import org.sonar.db.component.ComponentTesting; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.when; | |||
public class TrackerReferenceBranchInputFactoryTest { | |||
private final static String COMPONENT_KEY = "file1"; | |||
private final static String COMPONENT_UUID = "uuid1"; | |||
@Rule | |||
public DbTester db = DbTester.create(); | |||
private ComponentIssuesLoader componentIssuesLoader = mock(ComponentIssuesLoader.class); | |||
private ReferenceBranchComponentUuids referenceBranchComponentUuids = mock(ReferenceBranchComponentUuids.class); | |||
private TrackerReferenceBranchInputFactory underTest; | |||
@Before | |||
public void setUp() { | |||
underTest = new TrackerReferenceBranchInputFactory(componentIssuesLoader, referenceBranchComponentUuids, db.getDbClient()); | |||
} | |||
@Test | |||
public void gets_issues_and_hashes_in_matching_component() { | |||
DefaultIssue issue1 = new DefaultIssue(); | |||
when(referenceBranchComponentUuids.getComponentUuid(COMPONENT_KEY)).thenReturn(COMPONENT_UUID); | |||
when(componentIssuesLoader.loadOpenIssuesWithChanges(COMPONENT_UUID)).thenReturn(Collections.singletonList(issue1)); | |||
ComponentDto fileDto = ComponentTesting.newFileDto(ComponentTesting.newPublicProjectDto(db.getDefaultOrganization())).setUuid(COMPONENT_UUID); | |||
db.fileSources().insertFileSource(fileDto, 3); | |||
Component component = mock(Component.class); | |||
when(component.getDbKey()).thenReturn(COMPONENT_KEY); | |||
when(component.getType()).thenReturn(Component.Type.FILE); | |||
Input<DefaultIssue> input = underTest.create(component); | |||
assertThat(input.getIssues()).containsOnly(issue1); | |||
assertThat(input.getLineHashSequence().length()).isEqualTo(3); | |||
} | |||
@Test | |||
public void gets_nothing_when_there_is_no_matching_component() { | |||
Component component = mock(Component.class); | |||
when(component.getDbKey()).thenReturn(COMPONENT_KEY); | |||
when(component.getType()).thenReturn(Component.Type.FILE); | |||
Input<DefaultIssue> input = underTest.create(component); | |||
assertThat(input.getIssues()).isEmpty(); | |||
assertThat(input.getLineHashSequence().length()).isEqualTo(0); | |||
} | |||
} |
@@ -537,7 +537,7 @@ public class NotificationFactoryTest { | |||
@Test | |||
@UseDataProvider("noBranchNameBranches") | |||
public void newIssuesChangesNotification_creates_project_from_TreeRootHolder_and_branch_name_only_on_long_non_main_branches(Branch branch) { | |||
public void newIssuesChangesNotification_creates_project_from_TreeRootHolder_and_branch_name_only_on_non_main_branches(Branch branch) { | |||
RuleKey ruleKey = RuleKey.of("foo", "bar"); | |||
DefaultIssue issue = new DefaultIssue() | |||
.setRuleKey(ruleKey) | |||
@@ -592,7 +592,7 @@ public class NotificationFactoryTest { | |||
ruleRepository.add(ruleKey); | |||
treeRootHolder.setRoot(project); | |||
analysisMetadata.setAnalysisDate(new Random().nextLong()); | |||
analysisMetadata.setBranch(newBranch(BranchType.BRANCH, branchName)); | |||
analysisMetadata.setBranch(newNonMainBranch(BranchType.BRANCH, branchName)); | |||
IssuesChangesNotification expected = mock(IssuesChangesNotification.class); | |||
when(issuesChangesSerializer.serialize(any(IssuesChangesNotificationBuilder.class))).thenReturn(expected); | |||
@@ -622,7 +622,7 @@ public class NotificationFactoryTest { | |||
ruleRepository.add(ruleKey); | |||
treeRootHolder.setRoot(project); | |||
analysisMetadata.setAnalysisDate(new Random().nextLong()); | |||
analysisMetadata.setBranch(newBranch(BranchType.BRANCH, branchName)); | |||
analysisMetadata.setBranch(newNonMainBranch(BranchType.BRANCH, branchName)); | |||
IssuesChangesNotification expected = mock(IssuesChangesNotification.class); | |||
when(issuesChangesSerializer.serialize(any(IssuesChangesNotificationBuilder.class))).thenReturn(expected); | |||
@@ -650,7 +650,7 @@ public class NotificationFactoryTest { | |||
ruleRepository.add(ruleKey); | |||
treeRootHolder.setRoot(project); | |||
analysisMetadata.setAnalysisDate(new Random().nextLong()); | |||
analysisMetadata.setBranch(newBranch(BranchType.BRANCH, randomAlphabetic(12))); | |||
analysisMetadata.setBranch(newNonMainBranch(BranchType.BRANCH, randomAlphabetic(12))); | |||
expectedException.expect(IllegalStateException.class); | |||
expectedException.expectMessage("Can not find DTO for assignee uuid " + assigneeUuid); | |||
@@ -673,7 +673,7 @@ public class NotificationFactoryTest { | |||
ruleRepository.add(ruleKey); | |||
treeRootHolder.setRoot(project); | |||
analysisMetadata.setAnalysisDate(new Random().nextLong()); | |||
analysisMetadata.setBranch(newBranch(BranchType.BRANCH, randomAlphabetic(12))); | |||
analysisMetadata.setBranch(newNonMainBranch(BranchType.BRANCH, randomAlphabetic(12))); | |||
IssuesChangesNotification expected = mock(IssuesChangesNotification.class); | |||
when(issuesChangesSerializer.serialize(any(IssuesChangesNotificationBuilder.class))).thenReturn(expected); | |||
@@ -703,7 +703,7 @@ public class NotificationFactoryTest { | |||
ruleRepository.add(ruleKey); | |||
treeRootHolder.setRoot(project); | |||
analysisMetadata.setAnalysisDate(analysisDate); | |||
analysisMetadata.setBranch(newBranch(BranchType.BRANCH, randomAlphabetic(12))); | |||
analysisMetadata.setBranch(newNonMainBranch(BranchType.BRANCH, randomAlphabetic(12))); | |||
IssuesChangesNotification expected = mock(IssuesChangesNotification.class); | |||
when(issuesChangesSerializer.serialize(any(IssuesChangesNotificationBuilder.class))).thenReturn(expected); | |||
@@ -733,7 +733,7 @@ public class NotificationFactoryTest { | |||
.forEach(ruleKey -> ruleRepository.add(ruleKey)); | |||
treeRootHolder.setRoot(project); | |||
analysisMetadata.setAnalysisDate(analysisDate); | |||
analysisMetadata.setBranch(newBranch(BranchType.BRANCH, randomAlphabetic(12))); | |||
analysisMetadata.setBranch(newNonMainBranch(BranchType.BRANCH, randomAlphabetic(12))); | |||
IssuesChangesNotification expected = mock(IssuesChangesNotification.class); | |||
when(issuesChangesSerializer.serialize(any(IssuesChangesNotificationBuilder.class))).thenReturn(expected); | |||
@@ -769,12 +769,12 @@ public class NotificationFactoryTest { | |||
return builderCaptor.getValue(); | |||
} | |||
private static Branch newBranch(BranchType branchType, String branchName) { | |||
Branch longBranch = mock(Branch.class); | |||
when(longBranch.isMain()).thenReturn(false); | |||
when(longBranch.getType()).thenReturn(branchType); | |||
when(longBranch.getName()).thenReturn(branchName); | |||
return longBranch; | |||
private static Branch newNonMainBranch(BranchType branchType, String branchName) { | |||
Branch nonMainBranch = mock(Branch.class); | |||
when(nonMainBranch.isMain()).thenReturn(false); | |||
when(nonMainBranch.getType()).thenReturn(branchType); | |||
when(nonMainBranch.getName()).thenReturn(branchName); | |||
return nonMainBranch; | |||
} | |||
private static Durations readDurationsField(NewIssuesNotification notification) { |
@@ -34,7 +34,7 @@ import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolderRule; | |||
import org.sonar.ce.task.projectanalysis.analysis.Branch; | |||
import org.sonar.ce.task.projectanalysis.batch.BatchReportReaderRule; | |||
import org.sonar.ce.task.projectanalysis.component.Component; | |||
import org.sonar.ce.task.projectanalysis.component.MergeAndTargetBranchComponentUuids; | |||
import org.sonar.ce.task.projectanalysis.component.ReferenceBranchComponentUuids; | |||
import org.sonar.core.hash.SourceHashComputer; | |||
import org.sonar.db.DbTester; | |||
import org.sonar.db.component.BranchType; | |||
@@ -70,9 +70,9 @@ public class ScmInfoDbLoaderTest { | |||
public BatchReportReaderRule reportReader = new BatchReportReaderRule(); | |||
private Branch branch = mock(Branch.class); | |||
private MergeAndTargetBranchComponentUuids mergeAndTargetBranchComponentUuids = mock(MergeAndTargetBranchComponentUuids.class); | |||
private ReferenceBranchComponentUuids referenceBranchComponentUuids = mock(ReferenceBranchComponentUuids.class); | |||
private ScmInfoDbLoader underTest = new ScmInfoDbLoader(analysisMetadataHolder, dbTester.getDbClient(), mergeAndTargetBranchComponentUuids); | |||
private ScmInfoDbLoader underTest = new ScmInfoDbLoader(analysisMetadataHolder, dbTester.getDbClient(), referenceBranchComponentUuids); | |||
@Test | |||
public void returns_ScmInfo_from_DB() { | |||
@@ -90,20 +90,20 @@ public class ScmInfoDbLoaderTest { | |||
} | |||
@Test | |||
public void read_from_merge_branch_if_no_base() { | |||
public void read_from_reference_branch_if_no_base() { | |||
analysisMetadataHolder.setBaseAnalysis(null); | |||
analysisMetadataHolder.setBranch(branch); | |||
String mergeFileUuid = "mergeFileUuid"; | |||
String referenceFileUuid = "referenceFileUuid"; | |||
String hash = computeSourceHash(1); | |||
when(mergeAndTargetBranchComponentUuids.getMergeBranchComponentUuid(FILE.getDbKey())).thenReturn(mergeFileUuid); | |||
addFileSourceInDb("henry", DATE_1, "rev-1", hash, mergeFileUuid); | |||
when(referenceBranchComponentUuids.getComponentUuid(FILE.getDbKey())).thenReturn(referenceFileUuid); | |||
addFileSourceInDb("henry", DATE_1, "rev-1", hash, referenceFileUuid); | |||
DbScmInfo scmInfo = underTest.getScmInfo(FILE).get(); | |||
assertThat(scmInfo.getAllChangesets()).hasSize(1); | |||
assertThat(scmInfo.fileHash()).isEqualTo(hash); | |||
assertThat(logTester.logs(TRACE)).containsOnly("Reading SCM info from DB for file 'mergeFileUuid'"); | |||
assertThat(logTester.logs(TRACE)).containsOnly("Reading SCM info from DB for file 'referenceFileUuid'"); | |||
} | |||
@Test | |||
@@ -116,7 +116,7 @@ public class ScmInfoDbLoaderTest { | |||
String targetBranchFileUuid = "targetBranchFileUuid"; | |||
String hash = computeSourceHash(1); | |||
when(mergeAndTargetBranchComponentUuids.getMergeBranchComponentUuid(FILE.getDbKey())).thenReturn(targetBranchFileUuid); | |||
when(referenceBranchComponentUuids.getComponentUuid(FILE.getDbKey())).thenReturn(targetBranchFileUuid); | |||
addFileSourceInDb("henry", DATE_1, "rev-1", hash, targetBranchFileUuid); | |||
DbScmInfo scmInfo = underTest.getScmInfo(FILE).get(); | |||
@@ -137,7 +137,7 @@ public class ScmInfoDbLoaderTest { | |||
} | |||
@Test | |||
public void do_not_read_from_db_on_first_analysis_if_there_is_no_merge_branch() { | |||
public void do_not_read_from_db_on_first_analysis_if_there_is_no_reference_branch() { | |||
Branch branch = mock(Branch.class); | |||
when(branch.getType()).thenReturn(BranchType.PULL_REQUEST); | |||
analysisMetadataHolder.setBaseAnalysis(null); | |||
@@ -147,18 +147,6 @@ public class ScmInfoDbLoaderTest { | |||
assertThat(logTester.logs(TRACE)).isEmpty(); | |||
} | |||
@Test | |||
public void do_not_read_from_db_on_pr_is_there_is_no_target_and_merge_branch() { | |||
analysisMetadataHolder.setBaseAnalysis(null); | |||
analysisMetadataHolder.setBranch(mock(Branch.class)); | |||
assertThat(underTest.getScmInfo(FILE)).isEmpty(); | |||
assertThat(logTester.logs(TRACE)).isEmpty(); | |||
verify(mergeAndTargetBranchComponentUuids).getMergeBranchComponentUuid(FILE.getDbKey()); | |||
verify(mergeAndTargetBranchComponentUuids).getTargetBranchComponentUuid(FILE.getDbKey()); | |||
} | |||
private static List<String> generateLines(int lineCount) { | |||
ImmutableList.Builder<String> builder = ImmutableList.builder(); | |||
for (int i = 0; i < lineCount; i++) { |
@@ -20,12 +20,11 @@ | |||
package org.sonar.ce.task.projectanalysis.source; | |||
import java.util.Arrays; | |||
import javax.annotation.Nullable; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder; | |||
import org.sonar.ce.task.projectanalysis.component.Component; | |||
import org.sonar.ce.task.projectanalysis.component.MergeAndTargetBranchComponentUuids; | |||
import org.sonar.ce.task.projectanalysis.component.ReferenceBranchComponentUuids; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.component.ComponentDao; | |||
@@ -45,10 +44,10 @@ public class SourceLinesDiffImplTest { | |||
private FileSourceDao fileSourceDao = mock(FileSourceDao.class); | |||
private SourceLinesHashRepository sourceLinesHash = mock(SourceLinesHashRepository.class); | |||
private AnalysisMetadataHolder analysisMetadataHolder = mock(AnalysisMetadataHolder.class); | |||
private MergeAndTargetBranchComponentUuids mergeAndTargetBranchComponentUuids = mock(MergeAndTargetBranchComponentUuids.class); | |||
private ReferenceBranchComponentUuids referenceBranchComponentUuids = mock(ReferenceBranchComponentUuids.class); | |||
private SourceLinesDiffImpl underTest = new SourceLinesDiffImpl(dbClient, fileSourceDao, sourceLinesHash, | |||
mergeAndTargetBranchComponentUuids, analysisMetadataHolder); | |||
referenceBranchComponentUuids, analysisMetadataHolder); | |||
private static final int FILE_REF = 1; | |||
@@ -70,29 +69,14 @@ public class SourceLinesDiffImplTest { | |||
} | |||
@Test | |||
public void should_find_diff_with_target_branch_for_prs() { | |||
public void should_find_diff_with_reference_branch_for_prs() { | |||
Component component = fileComponent(FILE_REF); | |||
Component componentInTarget = fileComponent(2); | |||
mockLineHashesInDb(2, CONTENT); | |||
setLineHashesInReport(component, CONTENT); | |||
when(analysisMetadataHolder.isPullRequest()).thenReturn(true); | |||
when(mergeAndTargetBranchComponentUuids.getTargetBranchComponentUuid(component.getKey())).thenReturn("uuid_2"); | |||
assertThat(underTest.computeMatchingLines(component)).containsExactly(1, 2, 3, 4, 5, 6, 7); | |||
} | |||
@Test | |||
public void should_find_diff_with_merge_branch_for_prs_if_not_found_in_target() { | |||
Component component = fileComponent(FILE_REF); | |||
Component componentInTarget = fileComponent(2); | |||
mockLineHashesInDb(2, CONTENT); | |||
setLineHashesInReport(component, CONTENT); | |||
when(analysisMetadataHolder.isPullRequest()).thenReturn(true); | |||
when(mergeAndTargetBranchComponentUuids.getMergeBranchComponentUuid(component.getKey())).thenReturn("uuid_2"); | |||
when(referenceBranchComponentUuids.getComponentUuid(component.getKey())).thenReturn("uuid_2"); | |||
assertThat(underTest.computeMatchingLines(component)).containsExactly(1, 2, 3, 4, 5, 6, 7); | |||
} | |||
@@ -116,7 +100,7 @@ public class SourceLinesDiffImplTest { | |||
assertThat(underTest.computeMatchingLines(component)).containsExactly(1, 2, 3, 4, 5, 6, 7); | |||
} | |||
private void mockLineHashesInDb(int ref, @Nullable String[] lineHashes) { | |||
private void mockLineHashesInDb(int ref, String[] lineHashes) { | |||
when(fileSourceDao.selectLineHashes(dbSession, componentUuidOf(String.valueOf(ref)))) | |||
.thenReturn(Arrays.asList(lineHashes)); | |||
} |
@@ -671,7 +671,7 @@ public class ReportPersistComponentsStepTest extends BaseStepTest { | |||
} | |||
@Override | |||
public String getMergeBranchUuid() { | |||
public String getReferenceBranchUuid() { | |||
throw new UnsupportedOperationException(); | |||
} | |||
@@ -101,7 +101,7 @@ public class ValidateProjectStepTest { | |||
private void setBranch(BranchType type, @Nullable String mergeBranchUuid) { | |||
Branch branch = mock(Branch.class); | |||
when(branch.getType()).thenReturn(type); | |||
when(branch.getMergeBranchUuid()).thenReturn(mergeBranchUuid); | |||
when(branch.getReferenceBranchUuid()).thenReturn(mergeBranchUuid); | |||
analysisMetadataHolder.setBranch(branch); | |||
} | |||
@@ -20,16 +20,6 @@ | |||
package org.sonar.db.component; | |||
public enum BranchType { | |||
/** | |||
* Short-lived branch | |||
*/ | |||
SHORT, | |||
BRANCH, | |||
/** | |||
* Pull request | |||
*/ | |||
PULL_REQUEST | |||
} |
@@ -348,7 +348,7 @@ public class ComponentDao implements Dao { | |||
} | |||
/** | |||
* Returns components with open issues from branches that use a certain long living branch as reference (merge branch). | |||
* Returns components with open issues from P/Rs that use a certain branch as reference (reference branch). | |||
* Excludes components from the current branch. | |||
*/ | |||
public List<KeyWithUuidDto> selectAllSiblingComponentKeysHavingOpenIssues(DbSession dbSession, String referenceBranchUuid, String currentBranchUuid) { |
@@ -72,7 +72,7 @@ public final class PrIssueDto implements Serializable { | |||
} | |||
/** | |||
* Branch name for SLB, PR key for PR | |||
* Branch name for BRANCH, PR key for PR | |||
*/ | |||
public String getBranchKey() { | |||
return branchKey; |
@@ -102,8 +102,8 @@ public class LiveMeasureDao implements Dao { | |||
* If Main Branch = 100 LOCs and the "largest branch" is 120 LOCs, I'm expecting to consider the value 120. | |||
* If Main Branch = 100 LOCs and the "largest branch" is 80 LOCs, I'm expecting to consider the value 100. | |||
*/ | |||
public long sumNclocOfBiggestLongLivingBranch(DbSession dbSession, SumNclocDbQuery dbQuery) { | |||
Long ncloc = mapper(dbSession).sumNclocOfBiggestLongLivingBranch( | |||
public long sumNclocOfBiggestBranch(DbSession dbSession, SumNclocDbQuery dbQuery) { | |||
Long ncloc = mapper(dbSession).sumNclocOfBiggestBranch( | |||
NCLOC_KEY, KeyType.BRANCH, BranchType.BRANCH, dbQuery.getOrganizationUuid(), dbQuery.getOnlyPrivateProjects(), dbQuery.getProjectUuidToExclude()); | |||
return ncloc == null ? 0L : ncloc; | |||
} |
@@ -52,7 +52,7 @@ public interface LiveMeasureMapper { | |||
@Param("baseUuidPath") String baseUuidPath, | |||
ResultHandler<LiveMeasureDto> resultHandler); | |||
Long sumNclocOfBiggestLongLivingBranch( | |||
Long sumNclocOfBiggestBranch( | |||
@Param("ncloc") String nclocKey, | |||
@Param("branch") KeyType branchOrPullRequest, | |||
@Param("branchType") BranchType branchType, |
@@ -760,7 +760,7 @@ | |||
ON p.uuid = i.component_uuid | |||
JOIN project_branches b | |||
ON i.project_uuid = b.uuid | |||
AND (b.branch_type = 'SHORT' OR b.branch_type = 'PULL_REQUEST') | |||
AND b.branch_type = 'PULL_REQUEST' | |||
AND b.merge_branch_uuid = #{referenceBranchUuid,jdbcType=VARCHAR} | |||
AND b.uuid != #{currentBranchUuid,jdbcType=VARCHAR} | |||
AND i.status != 'CLOSED' |
@@ -42,7 +42,7 @@ | |||
and lm.component_uuid = #{componentUuid, jdbcType=VARCHAR} | |||
</select> | |||
<select id="sumNclocOfBiggestLongLivingBranch" parameterType="map" resultType="long"> | |||
<select id="sumNclocOfBiggestBranch" parameterType="map" resultType="long"> | |||
select sum(sumncloc.maxncloc) from ( | |||
select b.project_uuid as projectUuid, max(lm.value) as maxncloc | |||
from live_measures lm |
@@ -277,9 +277,9 @@ public class LiveMeasureDaoTest { | |||
ComponentDto simpleProject = db.components().insertMainBranch(organization); | |||
db.measures().insertLiveMeasure(simpleProject, ncloc, m -> m.setValue(10d)); | |||
ComponentDto projectWithBiggerLongLivingBranch = db.components().insertMainBranch(organization); | |||
ComponentDto bigBranch = db.components().insertProjectBranch(projectWithBiggerLongLivingBranch, b -> b.setBranchType(BranchType.BRANCH)); | |||
db.measures().insertLiveMeasure(projectWithBiggerLongLivingBranch, ncloc, m -> m.setValue(100d)); | |||
ComponentDto projectWithBiggerBranch = db.components().insertMainBranch(organization); | |||
ComponentDto bigBranch = db.components().insertProjectBranch(projectWithBiggerBranch, b -> b.setBranchType(BranchType.BRANCH)); | |||
db.measures().insertLiveMeasure(projectWithBiggerBranch, ncloc, m -> m.setValue(100d)); | |||
db.measures().insertLiveMeasure(bigBranch, ncloc, m -> m.setValue(200d)); | |||
ComponentDto projectWithLinesButNoLoc = db.components().insertMainBranch(organization); | |||
@@ -290,7 +290,7 @@ public class LiveMeasureDaoTest { | |||
.setOnlyPrivateProjects(false) | |||
.setOrganizationUuid(organization.getUuid()) | |||
.build(); | |||
long result = underTest.sumNclocOfBiggestLongLivingBranch(db.getSession(), query); | |||
long result = underTest.sumNclocOfBiggestBranch(db.getSession(), query); | |||
assertThat(result).isEqualTo(10L + 200L); | |||
} | |||
@@ -303,7 +303,7 @@ public class LiveMeasureDaoTest { | |||
.setOnlyPrivateProjects(false) | |||
.setOrganizationUuid(db.getDefaultOrganization().getUuid()) | |||
.build(); | |||
long result = underTest.sumNclocOfBiggestLongLivingBranch(db.getSession(), query); | |||
long result = underTest.sumNclocOfBiggestBranch(db.getSession(), query); | |||
assertThat(result).isEqualTo(0L); | |||
} | |||
@@ -316,9 +316,9 @@ public class LiveMeasureDaoTest { | |||
ComponentDto simpleProject = db.components().insertMainBranch(organization); | |||
db.measures().insertLiveMeasure(simpleProject, ncloc, m -> m.setValue(10d)); | |||
ComponentDto projectWithBiggerLongLivingBranch = db.components().insertMainBranch(organization); | |||
ComponentDto bigBranch = db.components().insertProjectBranch(projectWithBiggerLongLivingBranch, b -> b.setBranchType(BranchType.BRANCH)); | |||
db.measures().insertLiveMeasure(projectWithBiggerLongLivingBranch, ncloc, m -> m.setValue(100d)); | |||
ComponentDto projectWithBiggerBranch = db.components().insertMainBranch(organization); | |||
ComponentDto bigBranch = db.components().insertProjectBranch(projectWithBiggerBranch, b -> b.setBranchType(BranchType.BRANCH)); | |||
db.measures().insertLiveMeasure(projectWithBiggerBranch, ncloc, m -> m.setValue(100d)); | |||
db.measures().insertLiveMeasure(bigBranch, ncloc, m -> m.setValue(200d)); | |||
ComponentDto projectToExclude = db.components().insertMainBranch(organization); | |||
@@ -331,7 +331,7 @@ public class LiveMeasureDaoTest { | |||
.setProjectUuidToExclude(projectToExclude.uuid()) | |||
.setOnlyPrivateProjects(false) | |||
.build(); | |||
long result = underTest.sumNclocOfBiggestLongLivingBranch(db.getSession(), query); | |||
long result = underTest.sumNclocOfBiggestBranch(db.getSession(), query); | |||
assertThat(result).isEqualTo(10L + 200L); | |||
} |
@@ -165,7 +165,7 @@ public class PurgeDaoTest { | |||
when(system2.now()).thenReturn(new Date().getTime()); | |||
RuleDefinitionDto rule = db.rules().insert(); | |||
ComponentDto project = db.components().insertMainBranch(); | |||
ComponentDto longBranch = db.components().insertProjectBranch(project); | |||
ComponentDto nonMainBranch = db.components().insertProjectBranch(project); | |||
ComponentDto recentPullRequest = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.PULL_REQUEST)); | |||
// pull request with other components and issues, updated 31 days ago | |||
@@ -181,7 +181,7 @@ public class PurgeDaoTest { | |||
underTest.purge(dbSession, newConfigurationWith30Days(System2.INSTANCE, project.uuid(), project.uuid()), PurgeListener.EMPTY, new PurgeProfiler()); | |||
dbSession.commit(); | |||
assertThat(uuidsIn("projects")).containsOnly(project.uuid(), longBranch.uuid(), recentPullRequest.uuid()); | |||
assertThat(uuidsIn("projects")).containsOnly(project.uuid(), nonMainBranch.uuid(), recentPullRequest.uuid()); | |||
} | |||
@Test | |||
@@ -189,7 +189,7 @@ public class PurgeDaoTest { | |||
when(system2.now()).thenReturn(new Date().getTime()); | |||
RuleDefinitionDto rule = db.rules().insert(); | |||
ComponentDto project = db.components().insertMainBranch(); | |||
ComponentDto longBranch = db.components().insertProjectBranch(project); | |||
ComponentDto nonMainBranch = db.components().insertProjectBranch(project); | |||
when(system2.now()).thenReturn(DateUtils.addDays(new Date(), -31).getTime()); | |||
@@ -208,7 +208,7 @@ public class PurgeDaoTest { | |||
dbSession.commit(); | |||
// branch1 wasn't deleted since it was being analyzed! | |||
assertThat(uuidsIn("projects")).containsOnly(project.uuid(), longBranch.uuid(), branch1.uuid()); | |||
assertThat(uuidsIn("projects")).containsOnly(project.uuid(), nonMainBranch.uuid(), branch1.uuid()); | |||
} | |||
@Test |
@@ -1,13 +0,0 @@ | |||
CREATE TABLE PROJECT_BRANCHES( | |||
UUID VARCHAR(50) NOT NULL, | |||
PROJECT_UUID VARCHAR(50) NOT NULL, | |||
KEE VARCHAR(255) NOT NULL, | |||
BRANCH_TYPE VARCHAR(12), | |||
MERGE_BRANCH_UUID VARCHAR(50), | |||
KEY_TYPE VARCHAR(12) NOT NULL, | |||
PULL_REQUEST_BINARY BLOB, | |||
MANUAL_BASELINE_ANALYSIS_UUID VARCHAR(40), | |||
CREATED_AT BIGINT NOT NULL, | |||
UPDATED_AT BIGINT NOT NULL, | |||
EXCLUDE_FROM_PURGE BOOLEAN | |||
); |
@@ -55,8 +55,7 @@ public class IssueFieldsSetter { | |||
public static final String STATUS = "status"; | |||
public static final String AUTHOR = "author"; | |||
public static final String FILE = "file"; | |||
public static final String FROM_LONG_BRANCH = "from_long_branch"; | |||
public static final String FROM_SHORT_BRANCH = "from_short_branch"; | |||
public static final String FROM_BRANCH = "from_branch"; | |||
/** | |||
* It should be renamed to 'effort', but it hasn't been done to prevent a massive update in database |
@@ -49,7 +49,7 @@ public final class Branch { | |||
} | |||
public enum Type { | |||
LONG, SHORT, PULL_REQUEST, BRANCH | |||
PULL_REQUEST, BRANCH | |||
} | |||
@Override |
@@ -105,7 +105,7 @@ public class ProjectAnalysisTest { | |||
assertThat(underTest).isNotEqualTo(new ProjectAnalysis(project, ceTask, null, null, qualityGate, 1L, properties)); | |||
assertThat(underTest).isNotEqualTo(new ProjectAnalysis(project, ceTask, new Analysis("foo", 1_500L, "sha1"), null, qualityGate, 1L, properties)); | |||
assertThat(underTest).isNotEqualTo(new ProjectAnalysis(project, ceTask, analysis, null, qualityGate, 1L, properties)); | |||
assertThat(underTest).isNotEqualTo(new ProjectAnalysis(project, ceTask, analysis, new Branch(false, "B", Branch.Type.LONG), qualityGate, 1L, properties)); | |||
assertThat(underTest).isNotEqualTo(new ProjectAnalysis(project, ceTask, analysis, new Branch(false, "B", Branch.Type.BRANCH), qualityGate, 1L, properties)); | |||
assertThat(underTest).isNotEqualTo(new ProjectAnalysis(project, ceTask, analysis, branch, null, 1L, properties)); | |||
EvaluatedQualityGate otherQualityGate = EvaluatedQualityGate.newBuilder() | |||
.setQualityGate(new QualityGate("A", "B", emptySet())) | |||
@@ -131,7 +131,7 @@ public class ProjectAnalysisTest { | |||
assertThat(underTest.hashCode()).isNotEqualTo(new ProjectAnalysis(project, ceTask, new Analysis("foo", 1_500L, "sha1"), null, qualityGate, 1L, properties).hashCode()); | |||
assertThat(underTest.hashCode()).isNotEqualTo(new ProjectAnalysis(project, ceTask, analysis, null, qualityGate, 1L, properties).hashCode()); | |||
assertThat(underTest.hashCode()) | |||
.isNotEqualTo(new ProjectAnalysis(project, ceTask, analysis, new Branch(false, "B", Branch.Type.SHORT), qualityGate, 1L, properties).hashCode()); | |||
.isNotEqualTo(new ProjectAnalysis(project, ceTask, analysis, new Branch(false, "B", Branch.Type.BRANCH), qualityGate, 1L, properties).hashCode()); | |||
assertThat(underTest.hashCode()).isNotEqualTo(new ProjectAnalysis(project, ceTask, analysis, branch, null, 1L, properties).hashCode()); | |||
EvaluatedQualityGate otherQualityGate = EvaluatedQualityGate.newBuilder() | |||
.setQualityGate(new QualityGate("A", "B", emptySet())) |
@@ -114,7 +114,7 @@ public class TelemetryDataLoaderImpl implements TelemetryDataLoader { | |||
.setOnlyPrivateProjects(false) | |||
.setOrganizationUuid(defaultOrganizationProvider.get().getUuid()) | |||
.build(); | |||
data.setNcloc(dbClient.liveMeasureDao().sumNclocOfBiggestLongLivingBranch(dbSession, query)); | |||
data.setNcloc(dbClient.liveMeasureDao().sumNclocOfBiggestBranch(dbSession, query)); | |||
} | |||
Optional<String> installationDateProperty = internalProperties.read(InternalProperties.INSTALLATION_DATE); |
@@ -199,15 +199,15 @@ public class WebhookQGChangeEventListenerTest { | |||
public void onIssueChangesCallsWebhookOnBranch(BranchType branchType) { | |||
OrganizationDto organization = dbTester.organizations().insert(); | |||
ComponentAndBranch mainBranch = insertMainBranch(organization); | |||
ComponentAndBranch longBranch = insertProjectBranch(mainBranch.component, branchType, "foo"); | |||
SnapshotDto analysis = insertAnalysisTask(longBranch); | |||
ComponentAndBranch nonMainBranch = insertProjectBranch(mainBranch.component, branchType, "foo"); | |||
SnapshotDto analysis = insertAnalysisTask(nonMainBranch); | |||
Configuration configuration = mock(Configuration.class); | |||
QGChangeEvent qualityGateEvent = newQGChangeEvent(longBranch, analysis, configuration, null); | |||
QGChangeEvent qualityGateEvent = newQGChangeEvent(nonMainBranch, analysis, configuration, null); | |||
mockWebhookEnabled(qualityGateEvent.getProject()); | |||
underTest.onIssueChanges(qualityGateEvent, CHANGED_ISSUES_ARE_IGNORED); | |||
verifyWebhookCalled(longBranch, analysis, qualityGateEvent.getProject()); | |||
verifyWebhookCalled(nonMainBranch, analysis, qualityGateEvent.getProject()); | |||
} | |||
@DataProvider |
@@ -97,7 +97,7 @@ public class IssueUpdater { | |||
issue.updateDate() == null | |||
// name of rule is displayed in notification, rule must therefor be present | |||
|| !rule.isPresent() | |||
// notification are not supported on PRs and short lived branches | |||
// notification are not supported on PRs | |||
|| !hasNotificationSupport(branchDto)) { | |||
return issueDto; | |||
} |
@@ -66,7 +66,7 @@ public class ListAction implements NewCodePeriodsWsAction { | |||
@Override | |||
public void define(WebService.NewController context) { | |||
WebService.NewAction action = context.createAction("list") | |||
.setDescription("List the New Code Periods for all long lived branches in a project.<br>" + | |||
.setDescription("List the New Code Periods for all branches in a project.<br>" + | |||
"Requires the permission to browse the project") | |||
.setSince("8.0") | |||
.setResponseExample(getClass().getResource("list-example.json")) |
@@ -60,7 +60,7 @@ public class SetBaselineAction implements ProjectAnalysesWsAction { | |||
@Override | |||
public void define(WebService.NewController context) { | |||
WebService.NewAction action = context.createAction("set_baseline") | |||
.setDescription("Set an analysis as the baseline of the New Code Period on a project or a long-lived branch.<br/>" + | |||
.setDescription("Set an analysis as the baseline of the New Code Period on a project or a branch.<br/>" + | |||
"This manually set baseline.<br/>" + | |||
"Requires one of the following permissions:" + | |||
"<ul>" + |
@@ -53,7 +53,7 @@ public class UnsetBaselineAction implements ProjectAnalysesWsAction { | |||
@Override | |||
public void define(WebService.NewController context) { | |||
WebService.NewAction action = context.createAction("unset_baseline") | |||
.setDescription("Unset any manually-set New Code Period baseline on a project or a long-lived branch.<br/>" + | |||
.setDescription("Unset any manually-set New Code Period baseline on a project or a branch.<br/>" + | |||
"Unsetting a manual baseline restores the use of the default new code period setting.<br/>" + | |||
"Requires one of the following permissions:" + | |||
"<ul>" + |
@@ -162,19 +162,20 @@ public class ComponentAction implements NavigationWsAction { | |||
OrganizationDto org = componentFinder.getOrganization(session, component); | |||
Optional<SnapshotDto> analysis = dbClient.snapshotDao().selectLastAnalysisByRootComponentUuid(session, component.projectUuid()); | |||
JsonWriter json = response.newJsonWriter(); | |||
json.beginObject(); | |||
writeComponent(json, session, component, org, analysis.orElse(null)); | |||
writeAlmDetails(json, session, rootProject); | |||
writeProfiles(json, session, component); | |||
writeQualityGate(json, session, org, rootProject); | |||
if (userSession.hasComponentPermission(ADMIN, component) || | |||
userSession.hasPermission(ADMINISTER_QUALITY_PROFILES, org) || | |||
userSession.hasPermission(ADMINISTER_QUALITY_GATES, org)) { | |||
writeConfiguration(json, component, org); | |||
try (JsonWriter json = response.newJsonWriter()) { | |||
json.beginObject(); | |||
writeComponent(json, session, component, org, analysis.orElse(null)); | |||
writeAlmDetails(json, session, rootProject); | |||
writeProfiles(json, session, component); | |||
writeQualityGate(json, session, org, rootProject); | |||
if (userSession.hasComponentPermission(ADMIN, component) || | |||
userSession.hasPermission(ADMINISTER_QUALITY_PROFILES, org) || | |||
userSession.hasPermission(ADMINISTER_QUALITY_GATES, org)) { | |||
writeConfiguration(json, component, org); | |||
} | |||
writeBreadCrumbs(json, session, component); | |||
json.endObject().close(); | |||
} | |||
writeBreadCrumbs(json, session, component); | |||
json.endObject().close(); | |||
} | |||
} | |||
@@ -75,7 +75,7 @@ public class MarketplaceAction implements NavigationWsAction { | |||
.setOnlyPrivateProjects(false) | |||
.setOrganizationUuid(defaultOrganizationProvider.get().getUuid()) | |||
.build(); | |||
return dbClient.liveMeasureDao().sumNclocOfBiggestLongLivingBranch(dbSession, query); | |||
return dbClient.liveMeasureDao().sumNclocOfBiggestBranch(dbSession, query); | |||
} | |||
} | |||
} |
@@ -215,7 +215,7 @@ public class MeasureActionTest { | |||
} | |||
@Test | |||
public void measure_on_long_living_branch() { | |||
public void measure_on_non_main_branch() { | |||
ComponentDto project = db.components().insertMainBranch(p -> p.setPrivate(false)); | |||
userSession.registerComponents(project); | |||
MetricDto metric = db.measures().insertMetric(m -> m.setKey(BUGS_KEY).setValueType(INT.name())); |
@@ -175,12 +175,12 @@ public class ListActionTest { | |||
public void pull_requests() { | |||
ComponentDto project = db.components().insertMainBranch(); | |||
userSession.logIn().addProjectPermission(UserRole.USER, project); | |||
ComponentDto longLivingBranch = db.components().insertProjectBranch(project, | |||
b -> b.setKey("long").setBranchType(BranchType.BRANCH)); | |||
ComponentDto pullRequestOnLong = db.components().insertProjectBranch(project, | |||
b -> b.setKey("pull_request_on_long") | |||
ComponentDto nonMainBranch = db.components().insertProjectBranch(project, | |||
b -> b.setKey("branch1").setBranchType(BranchType.BRANCH)); | |||
ComponentDto pullRequestOnNonMainBranch = db.components().insertProjectBranch(project, | |||
b -> b.setKey("pull_request_on_branch1") | |||
.setBranchType(PULL_REQUEST) | |||
.setMergeBranchUuid(longLivingBranch.uuid()) | |||
.setMergeBranchUuid(nonMainBranch.uuid()) | |||
.setPullRequestData(DbProjectBranches.PullRequestData.newBuilder().setBranch("feature/bar").build())); | |||
ComponentDto pullRequestOnMaster = db.components().insertProjectBranch(project, | |||
b -> b.setKey("pull_request_on_master") | |||
@@ -195,7 +195,7 @@ public class ListActionTest { | |||
assertThat(response.getPullRequestsList()) | |||
.extracting(PullRequest::getKey, PullRequest::getBase) | |||
.containsExactlyInAnyOrder( | |||
tuple(pullRequestOnLong.getPullRequest(), longLivingBranch.getBranch()), | |||
tuple(pullRequestOnNonMainBranch.getPullRequest(), nonMainBranch.getBranch()), | |||
tuple(pullRequestOnMaster.getPullRequest(), "master")); | |||
} | |||
@@ -243,11 +243,11 @@ public class ListActionTest { | |||
public void status_on_pull_requests() { | |||
ComponentDto project = db.components().insertMainBranch(); | |||
userSession.logIn().addProjectPermission(UserRole.USER, project); | |||
ComponentDto longLivingBranch = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH)); | |||
ComponentDto nonMainBranch = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH)); | |||
ComponentDto pullRequest = db.components().insertProjectBranch(project, | |||
b -> b.setKey("pr-123") | |||
.setBranchType(PULL_REQUEST) | |||
.setMergeBranchUuid(longLivingBranch.uuid()) | |||
.setMergeBranchUuid(nonMainBranch.uuid()) | |||
.setPullRequestData(DbProjectBranches.PullRequestData.newBuilder().setBranch("feature/bar").build())); | |||
db.measures().insertLiveMeasure(pullRequest, qualityGateStatus, m -> m.setData("ERROR")); | |||
RuleDefinitionDto rule = db.rules().insert(); | |||
@@ -276,11 +276,11 @@ public class ListActionTest { | |||
public void status_on_pull_request_with_no_issue() { | |||
ComponentDto project = db.components().insertMainBranch(); | |||
userSession.logIn().addProjectPermission(UserRole.USER, project); | |||
ComponentDto longLivingBranch = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH)); | |||
ComponentDto nonMainBranch = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH)); | |||
db.components().insertProjectBranch(project, | |||
b -> b.setKey("pr-123") | |||
.setBranchType(PULL_REQUEST) | |||
.setMergeBranchUuid(longLivingBranch.uuid()) | |||
.setMergeBranchUuid(nonMainBranch.uuid()) | |||
.setPullRequestData(DbProjectBranches.PullRequestData.newBuilder().setBranch("feature/bar").build())); | |||
issueIndexer.indexOnStartup(emptySet()); | |||
permissionIndexerTester.allowOnlyAnyone(project); | |||
@@ -296,7 +296,7 @@ public class ListActionTest { | |||
@Test | |||
public void response_contains_date_of_last_analysis() { | |||
Long lastAnalysisLongLivingBranch = dateToLong(parseDateTime("2017-04-01T00:00:00+0100")); | |||
Long lastAnalysisNonMainBranch = dateToLong(parseDateTime("2017-04-01T00:00:00+0100")); | |||
Long previousAnalysisPullRequest = dateToLong(parseDateTime("2017-04-02T00:00:00+0100")); | |||
Long lastAnalysisPullRequest = dateToLong(parseDateTime("2017-04-03T00:00:00+0100")); | |||
@@ -309,16 +309,16 @@ public class ListActionTest { | |||
.setMergeBranchUuid(project.uuid()) | |||
.setPullRequestData(DbProjectBranches.PullRequestData.newBuilder().setBranch("feature/pr1").build())); | |||
ComponentDto longLivingBranch2 = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH)); | |||
ComponentDto nonMainBranch2 = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH)); | |||
ComponentDto pullRequest2 = db.components().insertProjectBranch(project, | |||
b -> b.setKey("pr2") | |||
.setBranchType(PULL_REQUEST) | |||
.setMergeBranchUuid(longLivingBranch2.uuid()) | |||
.setMergeBranchUuid(nonMainBranch2.uuid()) | |||
.setPullRequestData(DbProjectBranches.PullRequestData.newBuilder().setBranch("feature/pr2").build())); | |||
db.getDbClient().snapshotDao().insert(db.getSession(), | |||
newAnalysis(longLivingBranch2).setCreatedAt(lastAnalysisLongLivingBranch)); | |||
newAnalysis(nonMainBranch2).setCreatedAt(lastAnalysisNonMainBranch)); | |||
db.getDbClient().snapshotDao().insert(db.getSession(), | |||
newAnalysis(pullRequest2).setCreatedAt(previousAnalysisPullRequest).setLast(false)); | |||
db.getDbClient().snapshotDao().insert(db.getSession(), |
@@ -105,7 +105,7 @@ public class SetBaselineActionTest { | |||
} | |||
@Test | |||
public void set_baseline_on_long_living_branch() { | |||
public void set_baseline_on_non_main_branch() { | |||
ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert()); | |||
BranchDto branch = ComponentTesting.newBranchDto(project.projectUuid(), BranchType.BRANCH); | |||
db.components().insertProjectBranch(project, branch); |
@@ -88,7 +88,7 @@ public class UnsetBaselineActionTest { | |||
} | |||
@Test | |||
public void does_not_fail_and_has_no_effect_when_there_is_no_baseline_on_long_living_branch() { | |||
public void does_not_fail_and_has_no_effect_when_there_is_no_baseline_on_non_main_branch() { | |||
ComponentDto project = db.components().insertMainBranch(db.organizations().insert()); | |||
ComponentDto branch = db.components().insertProjectBranch(project); | |||
SnapshotDto analysis = db.components().insertSnapshot(project); | |||
@@ -114,10 +114,10 @@ public class UnsetBaselineActionTest { | |||
} | |||
@Test | |||
public void unset_baseline_when_it_is_set_long_living_branch() { | |||
public void unset_baseline_when_it_is_set_non_main_branch() { | |||
ComponentDto project = db.components().insertMainBranch(db.organizations().insert()); | |||
ComponentDto branch = db.components().insertProjectBranch(project); | |||
SnapshotDto projectAnalysis = db.components().insertSnapshot(branch); | |||
db.components().insertSnapshot(branch); | |||
SnapshotDto branchAnalysis = db.components().insertSnapshot(project); | |||
db.newCodePeriods().insert(project.projectUuid(), branch.uuid(), NewCodePeriodType.SPECIFIC_ANALYSIS, branchAnalysis.getUuid()); | |||
@@ -178,7 +178,7 @@ zip.doFirst { | |||
// Check the size of the archive | |||
zip.doLast { | |||
def minLength = 202000000 | |||
def maxLength = 210000000 | |||
def maxLength = 211000000 | |||
def length = archiveFile.get().asFile.length() | |||
if (length < minLength) | |||
throw new GradleException("$archiveName size ($length) too small. Min is $minLength") |
@@ -96,7 +96,7 @@ public class DefaultIssue implements Issue, Trackable, org.sonar.api.ce.measure. | |||
// all changes | |||
// -- contains only current change (if any) on CE side unless reopening a closed issue or copying issue from base branch | |||
// when analyzing a long living branch from the first time | |||
// when analyzing a branch from the first time | |||
private List<FieldDiffs> changes = null; | |||
// true if the issue did not exist in the previous scan. |
@@ -36,6 +36,7 @@ public interface Trackable { | |||
/** | |||
* Trimmed message of issue | |||
*/ | |||
@CheckForNull | |||
String getMessage(); | |||
@CheckForNull |
@@ -1378,7 +1378,7 @@ quality_gates.conditions.new_code.long=Conditions on New Code | |||
quality_gates.conditions.new_code.description=Conditions on New Code apply to all branches and to Pull Requests. | |||
quality_gates.conditions.overall_code=On Overall Code | |||
quality_gates.conditions.overall_code.long=Conditions on Overall Code | |||
quality_gates.conditions.overall_code.description=Conditions on Overall Code apply to long living branches only. | |||
quality_gates.conditions.overall_code.description=Conditions on Overall Code apply to branches only. | |||
quality_gates.conditions.operator=Operator | |||
quality_gates.conditions.warning=Warning | |||
quality_gates.conditions.warning.tooltip=Warning status is deprecated and will disappear with the next update of the Quality Gate. |
@@ -27,7 +27,7 @@ import java.util.Optional; | |||
public interface Branch { | |||
enum Type { | |||
LONG, SHORT, BRANCH, PULL_REQUEST | |||
BRANCH, PULL_REQUEST | |||
} | |||
boolean isMain(); |
@@ -158,7 +158,7 @@ public class MetadataPublisher implements ReportPublisherStep { | |||
builder.setBranchType(branchType); | |||
String referenceBranch = branchConfiguration.referenceBranchName(); | |||
if (referenceBranch != null) { | |||
builder.setMergeBranchName(referenceBranch); | |||
builder.setReferenceBranchName(referenceBranch); | |||
} | |||
String targetBranchName = branchConfiguration.targetBranchName(); | |||
if (targetBranchName != null) { |
@@ -45,8 +45,8 @@ public interface BranchConfiguration { | |||
/** | |||
* The branch from which we should load project settings/quality profiles/compare changed files/... | |||
* For branches, it's the to default branch in case of first analysis, otherwise it's the branch itself. | |||
* For PR, we look at sonar.pullrequest.base (default to default branch). If it exists but is a short living branch or PR, we will | |||
* For branches, it's the default branch in case of first analysis, otherwise it's the branch itself. | |||
* For PR, we look at sonar.pullrequest.base (default to default branch). If it exists and is not a PR we use it. If it exists but is a PR, we will | |||
* transitively use its own target. If base is not analyzed, we will use default branch. | |||
* | |||
* @return null if the branch feature is not available or no branch was specified. |
@@ -383,7 +383,7 @@ public class ScannerMediumTester extends ExternalResource { | |||
private BranchType branchType = BranchType.BRANCH; | |||
private String branchName = null; | |||
private String branchTarget = null; | |||
private String longLivingSonarReferenceBranch = null; | |||
private String referenceBranchName = null; | |||
@Override | |||
public BranchType branchType() { | |||
@@ -405,7 +405,7 @@ public class ScannerMediumTester extends ExternalResource { | |||
@CheckForNull | |||
@Override | |||
public String referenceBranchName() { | |||
return longLivingSonarReferenceBranch; | |||
return referenceBranchName; | |||
} | |||
@Override | |||
@@ -462,8 +462,8 @@ public class ScannerMediumTester extends ExternalResource { | |||
return this; | |||
} | |||
public ScannerMediumTester setLongLivingSonarReferenceBranch(String longLivingSonarReferenceBranch) { | |||
this.branchConfiguration.longLivingSonarReferenceBranch = longLivingSonarReferenceBranch; | |||
public ScannerMediumTester setReferenceBranchName(String referenceBranchNam) { | |||
this.branchConfiguration.referenceBranchName = referenceBranchNam; | |||
return this; | |||
} | |||
@@ -103,13 +103,13 @@ public class BranchMediumTest { | |||
AnalysisResult result = getResult(tester | |||
.setBranchName(branchName) | |||
.setBranchTarget(branchTarget) | |||
.setLongLivingSonarReferenceBranch(branchTarget) | |||
.setReferenceBranchName(branchTarget) | |||
.setBranchType(BranchType.BRANCH)); | |||
ScannerReport.Metadata metadata = result.getReportReader().readMetadata(); | |||
assertThat(metadata.getBranchName()).isEqualTo(branchName); | |||
assertThat(metadata.getBranchType()).isEqualTo(ScannerReport.Metadata.BranchType.BRANCH); | |||
assertThat(metadata.getMergeBranchName()).isEqualTo(branchTarget); | |||
assertThat(metadata.getReferenceBranchName()).isEqualTo(branchTarget); | |||
} | |||
private AnalysisResult getResult(ScannerMediumTester tester) { |
@@ -236,7 +236,7 @@ public class MetadataPublisherTest { | |||
ScannerReport.Metadata metadata = reader.readMetadata(); | |||
assertThat(metadata.getBranchName()).isEqualTo(branchName); | |||
assertThat(metadata.getBranchType()).isEqualTo(ScannerReport.Metadata.BranchType.BRANCH); | |||
assertThat(metadata.getMergeBranchName()).isEmpty(); | |||
assertThat(metadata.getReferenceBranchName()).isEmpty(); | |||
assertThat(metadata.getTargetBranchName()).isEqualTo(targetName); | |||
} | |||
@@ -43,7 +43,7 @@ message Metadata { | |||
string branch_name = 9; | |||
BranchType branch_type = 10; | |||
string merge_branch_name = 11; | |||
string reference_branch_name = 11; | |||
string relative_path_from_scm_root = 12; | |||
string scm_revision_id = 13; | |||
@@ -71,7 +71,7 @@ message Metadata { | |||
enum BranchType { | |||
UNSET = 0; | |||
BRANCH = 1; | |||
PULL_REQUEST = 3; | |||
PULL_REQUEST = 2; | |||
} | |||
} | |||
@@ -122,12 +122,9 @@ enum RuleType { | |||
} | |||
enum BranchType { | |||
// Zero is required in order to not get LONG as default value | |||
// See http://androiddevblog.com/protocol-buffers-pitfall-adding-enum-values/ | |||
UNKNOWN_BRANCH_TYPE = 0; | |||
reserved 1, 2; | |||
LONG = 1; | |||
SHORT = 2; | |||
UNKNOWN_BRANCH_TYPE = 0; | |||
PULL_REQUEST = 3; | |||
BRANCH = 4; | |||
} |