Selaa lähdekoodia

SONAR-12673 Fix issue management

tags/8.1.0.31237
Duarte Meneses 4 vuotta sitten
vanhempi
commit
ebdae1d5b7
75 muutettua tiedostoa jossa 516 lisäystä ja 733 poistoa
  1. 1
    1
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/analysis/AnalysisMetadataHolder.java
  2. 2
    2
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/analysis/Branch.java
  3. 1
    1
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/BranchLoader.java
  4. 1
    1
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/BranchPersisterImpl.java
  5. 1
    1
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/DefaultBranchImpl.java
  6. 0
    136
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/MergeAndTargetBranchComponentUuids.java
  7. 1
    1
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/ProjectViewAttributes.java
  8. 95
    0
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/ReferenceBranchComponentUuids.java
  9. 1
    2
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/SiblingComponentsWithOpenIssues.java
  10. 4
    4
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulator.java
  11. 5
    5
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/IntegrateIssuesVisitor.java
  12. 8
    8
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/IssueLifecycle.java
  13. 5
    8
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/IssueTrackingDelegator.java
  14. 3
    4
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/PullRequestTrackerExecution.java
  15. 4
    4
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/ReferenceBranchTrackerExecution.java
  16. 6
    13
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/SiblingIssue.java
  17. 2
    2
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/SiblingsIssueMerger.java
  18. 5
    2
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/SiblingsIssuesLoader.java
  19. 1
    1
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/TrackerRawInputFactory.java
  20. 16
    34
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/TrackerReferenceBranchInputFactory.java
  21. 5
    9
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/ScmInfoDbLoader.java
  22. 5
    8
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/source/SourceLinesDiffImpl.java
  23. 4
    4
      server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/ValidateProjectStep.java
  24. 1
    1
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/api/posttask/PostProjectAnalysisTasksExecutorTest.java
  25. 1
    1
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/BranchPersisterImplTest.java
  26. 16
    48
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/ReferenceBranchComponentUuidsTest.java
  27. 78
    101
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/SiblingComponentsWithOpenIssuesTest.java
  28. 19
    17
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IntegrateIssuesVisitorTest.java
  29. 10
    126
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssueLifecycleTest.java
  30. 6
    6
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssueTrackingDelegatorTest.java
  31. 2
    2
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/ReferenceBranchTrackerExecutionTest.java
  32. 10
    11
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/SiblingsIssueMergerTest.java
  33. 81
    0
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/TrackerReferenceBranchInputFactoryTest.java
  34. 13
    13
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/notification/NotificationFactoryTest.java
  35. 10
    22
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/scm/ScmInfoDbLoaderTest.java
  36. 6
    22
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/source/SourceLinesDiffImplTest.java
  37. 1
    1
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ReportPersistComponentsStepTest.java
  38. 1
    1
      server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ValidateProjectStepTest.java
  39. 0
    10
      server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchType.java
  40. 1
    1
      server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDao.java
  41. 1
    1
      server/sonar-db-dao/src/main/java/org/sonar/db/issue/PrIssueDto.java
  42. 2
    2
      server/sonar-db-dao/src/main/java/org/sonar/db/measure/LiveMeasureDao.java
  43. 1
    1
      server/sonar-db-dao/src/main/java/org/sonar/db/measure/LiveMeasureMapper.java
  44. 1
    1
      server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml
  45. 1
    1
      server/sonar-db-dao/src/main/resources/org/sonar/db/measure/LiveMeasureMapper.xml
  46. 9
    9
      server/sonar-db-dao/src/test/java/org/sonar/db/measure/LiveMeasureDaoTest.java
  47. 4
    4
      server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeDaoTest.java
  48. 0
    13
      server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v80/MakeExcludeBranchFromPurgeColumnNotNullableTest/schema.sql
  49. 1
    2
      server/sonar-server-common/src/main/java/org/sonar/server/issue/IssueFieldsSetter.java
  50. 1
    1
      server/sonar-server-common/src/main/java/org/sonar/server/webhook/Branch.java
  51. 2
    2
      server/sonar-server-common/src/test/java/org/sonar/server/webhook/ProjectAnalysisTest.java
  52. 1
    1
      server/sonar-webserver-core/src/main/java/org/sonar/server/telemetry/TelemetryDataLoaderImpl.java
  53. 4
    4
      server/sonar-webserver-core/src/test/java/org/sonar/server/webhook/WebhookQGChangeEventListenerTest.java
  54. 1
    1
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/IssueUpdater.java
  55. 1
    1
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/newcodeperiod/ws/ListAction.java
  56. 1
    1
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectanalysis/ws/SetBaselineAction.java
  57. 1
    1
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectanalysis/ws/UnsetBaselineAction.java
  58. 13
    12
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/ui/ws/ComponentAction.java
  59. 1
    1
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/ui/ws/MarketplaceAction.java
  60. 1
    1
      server/sonar-webserver-webapi/src/test/java/org/sonar/server/badge/ws/MeasureActionTest.java
  61. 14
    14
      server/sonar-webserver-webapi/src/test/java/org/sonar/server/branch/pr/ws/ListActionTest.java
  62. 1
    1
      server/sonar-webserver-webapi/src/test/java/org/sonar/server/projectanalysis/ws/SetBaselineActionTest.java
  63. 3
    3
      server/sonar-webserver-webapi/src/test/java/org/sonar/server/projectanalysis/ws/UnsetBaselineActionTest.java
  64. 1
    1
      sonar-application/build.gradle
  65. 1
    1
      sonar-core/src/main/java/org/sonar/core/issue/DefaultIssue.java
  66. 1
    0
      sonar-core/src/main/java/org/sonar/core/issue/tracking/Trackable.java
  67. 1
    1
      sonar-core/src/main/resources/org/sonar/l10n/core.properties
  68. 1
    1
      sonar-plugin-api/src/main/java/org/sonar/api/ce/posttask/Branch.java
  69. 1
    1
      sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MetadataPublisher.java
  70. 2
    2
      sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/branch/BranchConfiguration.java
  71. 4
    4
      sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/ScannerMediumTester.java
  72. 2
    2
      sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/BranchMediumTest.java
  73. 1
    1
      sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MetadataPublisherTest.java
  74. 2
    2
      sonar-scanner-protocol/src/main/protobuf/scanner_report.proto
  75. 2
    5
      sonar-ws/src/main/protobuf/ws-commons.proto

+ 1
- 1
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/analysis/AnalysisMetadataHolder.java Näytä tiedosto

@@ -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
*/

+ 2
- 2
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/analysis/Branch.java Näytä tiedosto

@@ -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

+ 1
- 1
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/BranchLoader.java Näytä tiedosto

@@ -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;
}


+ 1
- 1
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/BranchPersisterImpl.java Näytä tiedosto

@@ -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) {

+ 1
- 1
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/DefaultBranchImpl.java Näytä tiedosto

@@ -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");
}


+ 0
- 136
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/MergeAndTargetBranchComponentUuids.java Näytä tiedosto

@@ -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);
}
}

+ 1
- 1
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/ProjectViewAttributes.java Näytä tiedosto

@@ -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;
}

+ 95
- 0
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/ReferenceBranchComponentUuids.java Näytä tiedosto

@@ -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);
}
}

+ 1
- 2
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/SiblingComponentsWithOpenIssues.java Näytä tiedosto

@@ -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());

+ 4
- 4
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulator.java Näytä tiedosto

@@ -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,

+ 5
- 5
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/IntegrateIssuesVisitor.java Näytä tiedosto

@@ -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);
}
}

+ 8
- 8
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/IssueLifecycle.java Näytä tiedosto

@@ -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()) {

+ 5
- 8
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/IssueTrackingDelegator.java Näytä tiedosto

@@ -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;
}

+ 3
- 4
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/PullRequestTrackerExecution.java Näytä tiedosto

@@ -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());
}

+ 4
- 4
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/ReferenceBranchTrackerExecution.java Näytä tiedosto

@@ -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));
}
}

+ 6
- 13
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/SiblingIssue.java Näytä tiedosto

@@ -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

+ 2
- 2
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/SiblingsIssueMerger.java Näytä tiedosto

@@ -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());
}
}
}

+ 5
- 2
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/SiblingsIssuesLoader.java Näytä tiedosto

@@ -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()));
}


+ 1
- 1
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/TrackerRawInputFactory.java Näytä tiedosto

@@ -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();

server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/TrackerMergeOrTargetBranchInputFactory.java → server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/TrackerReferenceBranchInputFactory.java Näytä tiedosto

@@ -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);
}
}


+ 5
- 9
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/scm/ScmInfoDbLoader.java Näytä tiedosto

@@ -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();

+ 5
- 8
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/source/SourceLinesDiffImpl.java Näytä tiedosto

@@ -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();
}

+ 4
- 4
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/ValidateProjectStep.java Näytä tiedosto

@@ -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()));
}

+ 1
- 1
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/api/posttask/PostProjectAnalysisTasksExecutorTest.java Näytä tiedosto

@@ -289,7 +289,7 @@ public class PostProjectAnalysisTasksExecutorTest {
}

@Override
public String getMergeBranchUuid() {
public String getReferenceBranchUuid() {
throw new UnsupportedOperationException();
}


+ 1
- 1
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/BranchPersisterImplTest.java Näytä tiedosto

@@ -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;
}

server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/MergeAndTargetBranchComponentUuidsTest.java → server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/ReferenceBranchComponentUuidsTest.java Näytä tiedosto

@@ -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();
}
}

+ 78
- 101
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/SiblingComponentsWithOpenIssuesTest.java Näytä tiedosto

@@ -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);
}
}

+ 19
- 17
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IntegrateIssuesVisitorTest.java Näytä tiedosto

@@ -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);


+ 10
- 126
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssueLifecycleTest.java Näytä tiedosto

@@ -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);
}

+ 6
- 6
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssueTrackingDelegatorTest.java Näytä tiedosto

@@ -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);
}

+ 2
- 2
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/ReferenceBranchTrackerExecutionTest.java Näytä tiedosto

@@ -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);

+ 10
- 11
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/SiblingsIssueMergerTest.java Näytä tiedosto

@@ -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();

+ 81
- 0
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/TrackerReferenceBranchInputFactoryTest.java Näytä tiedosto

@@ -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);
}
}

+ 13
- 13
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/notification/NotificationFactoryTest.java Näytä tiedosto

@@ -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) {

+ 10
- 22
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/scm/ScmInfoDbLoaderTest.java Näytä tiedosto

@@ -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++) {

+ 6
- 22
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/source/SourceLinesDiffImplTest.java Näytä tiedosto

@@ -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));
}

+ 1
- 1
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ReportPersistComponentsStepTest.java Näytä tiedosto

@@ -671,7 +671,7 @@ public class ReportPersistComponentsStepTest extends BaseStepTest {
}

@Override
public String getMergeBranchUuid() {
public String getReferenceBranchUuid() {
throw new UnsupportedOperationException();
}


+ 1
- 1
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ValidateProjectStepTest.java Näytä tiedosto

@@ -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);
}


+ 0
- 10
server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchType.java Näytä tiedosto

@@ -20,16 +20,6 @@
package org.sonar.db.component;

public enum BranchType {

/**
* Short-lived branch
*/
SHORT,

BRANCH,

/**
* Pull request
*/
PULL_REQUEST
}

+ 1
- 1
server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDao.java Näytä tiedosto

@@ -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) {

+ 1
- 1
server/sonar-db-dao/src/main/java/org/sonar/db/issue/PrIssueDto.java Näytä tiedosto

@@ -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;

+ 2
- 2
server/sonar-db-dao/src/main/java/org/sonar/db/measure/LiveMeasureDao.java Näytä tiedosto

@@ -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;
}

+ 1
- 1
server/sonar-db-dao/src/main/java/org/sonar/db/measure/LiveMeasureMapper.java Näytä tiedosto

@@ -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,

+ 1
- 1
server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml Näytä tiedosto

@@ -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'

+ 1
- 1
server/sonar-db-dao/src/main/resources/org/sonar/db/measure/LiveMeasureMapper.xml Näytä tiedosto

@@ -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

+ 9
- 9
server/sonar-db-dao/src/test/java/org/sonar/db/measure/LiveMeasureDaoTest.java Näytä tiedosto

@@ -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);
}

+ 4
- 4
server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeDaoTest.java Näytä tiedosto

@@ -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

+ 0
- 13
server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v80/MakeExcludeBranchFromPurgeColumnNotNullableTest/schema.sql Näytä tiedosto

@@ -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
);

+ 1
- 2
server/sonar-server-common/src/main/java/org/sonar/server/issue/IssueFieldsSetter.java Näytä tiedosto

@@ -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

+ 1
- 1
server/sonar-server-common/src/main/java/org/sonar/server/webhook/Branch.java Näytä tiedosto

@@ -49,7 +49,7 @@ public final class Branch {
}

public enum Type {
LONG, SHORT, PULL_REQUEST, BRANCH
PULL_REQUEST, BRANCH
}

@Override

+ 2
- 2
server/sonar-server-common/src/test/java/org/sonar/server/webhook/ProjectAnalysisTest.java Näytä tiedosto

@@ -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()))

+ 1
- 1
server/sonar-webserver-core/src/main/java/org/sonar/server/telemetry/TelemetryDataLoaderImpl.java Näytä tiedosto

@@ -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);

+ 4
- 4
server/sonar-webserver-core/src/test/java/org/sonar/server/webhook/WebhookQGChangeEventListenerTest.java Näytä tiedosto

@@ -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

+ 1
- 1
server/sonar-webserver-webapi/src/main/java/org/sonar/server/issue/ws/IssueUpdater.java Näytä tiedosto

@@ -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;
}

+ 1
- 1
server/sonar-webserver-webapi/src/main/java/org/sonar/server/newcodeperiod/ws/ListAction.java Näytä tiedosto

@@ -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"))

+ 1
- 1
server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectanalysis/ws/SetBaselineAction.java Näytä tiedosto

@@ -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>" +

+ 1
- 1
server/sonar-webserver-webapi/src/main/java/org/sonar/server/projectanalysis/ws/UnsetBaselineAction.java Näytä tiedosto

@@ -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>" +

+ 13
- 12
server/sonar-webserver-webapi/src/main/java/org/sonar/server/ui/ws/ComponentAction.java Näytä tiedosto

@@ -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();
}
}


+ 1
- 1
server/sonar-webserver-webapi/src/main/java/org/sonar/server/ui/ws/MarketplaceAction.java Näytä tiedosto

@@ -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);
}
}
}

+ 1
- 1
server/sonar-webserver-webapi/src/test/java/org/sonar/server/badge/ws/MeasureActionTest.java Näytä tiedosto

@@ -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()));

+ 14
- 14
server/sonar-webserver-webapi/src/test/java/org/sonar/server/branch/pr/ws/ListActionTest.java Näytä tiedosto

@@ -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(),

+ 1
- 1
server/sonar-webserver-webapi/src/test/java/org/sonar/server/projectanalysis/ws/SetBaselineActionTest.java Näytä tiedosto

@@ -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);

+ 3
- 3
server/sonar-webserver-webapi/src/test/java/org/sonar/server/projectanalysis/ws/UnsetBaselineActionTest.java Näytä tiedosto

@@ -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());


+ 1
- 1
sonar-application/build.gradle Näytä tiedosto

@@ -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")

+ 1
- 1
sonar-core/src/main/java/org/sonar/core/issue/DefaultIssue.java Näytä tiedosto

@@ -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.

+ 1
- 0
sonar-core/src/main/java/org/sonar/core/issue/tracking/Trackable.java Näytä tiedosto

@@ -36,6 +36,7 @@ public interface Trackable {
/**
* Trimmed message of issue
*/
@CheckForNull
String getMessage();

@CheckForNull

+ 1
- 1
sonar-core/src/main/resources/org/sonar/l10n/core.properties Näytä tiedosto

@@ -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.

+ 1
- 1
sonar-plugin-api/src/main/java/org/sonar/api/ce/posttask/Branch.java Näytä tiedosto

@@ -27,7 +27,7 @@ import java.util.Optional;
public interface Branch {

enum Type {
LONG, SHORT, BRANCH, PULL_REQUEST
BRANCH, PULL_REQUEST
}

boolean isMain();

+ 1
- 1
sonar-scanner-engine/src/main/java/org/sonar/scanner/report/MetadataPublisher.java Näytä tiedosto

@@ -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) {

+ 2
- 2
sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/branch/BranchConfiguration.java Näytä tiedosto

@@ -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.

+ 4
- 4
sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/ScannerMediumTester.java Näytä tiedosto

@@ -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;
}


+ 2
- 2
sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/branch/BranchMediumTest.java Näytä tiedosto

@@ -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) {

+ 1
- 1
sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MetadataPublisherTest.java Näytä tiedosto

@@ -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);
}


+ 2
- 2
sonar-scanner-protocol/src/main/protobuf/scanner_report.proto Näytä tiedosto

@@ -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;
}
}


+ 2
- 5
sonar-ws/src/main/protobuf/ws-commons.proto Näytä tiedosto

@@ -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;
}

Loading…
Peruuta
Tallenna