Browse Source

SONAR-16163 Process reference branch set by the scanner in the CE

tags/9.4.0.54424
Zipeng WU 2 years ago
parent
commit
15bf48aa6f

+ 5
- 0
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/analysis/AnalysisMetadataHolder.java View File

@@ -124,4 +124,9 @@ public interface AnalysisMetadataHolder {
* Scm Revision of the analysed code
*/
Optional<String> getScmRevision();

/**
* Reference branch for the new code period, set by scanner parameter sonar.newCode.referenceBranch
*/
Optional<String> getNewCodeReferenceBranch();
}

+ 17
- 0
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/analysis/AnalysisMetadataHolderImpl.java View File

@@ -48,6 +48,7 @@ public class AnalysisMetadataHolderImpl implements MutableAnalysisMetadataHolder
private final InitializedProperty<Map<String, QualityProfile>> qProfilesPerLanguage = new InitializedProperty<>();
private final InitializedProperty<Map<String, ScannerPlugin>> pluginsByKey = new InitializedProperty<>();
private final InitializedProperty<String> scmRevision = new InitializedProperty<>();
private final InitializedProperty<String> newCodeReferenceBranch = new InitializedProperty<>();

private final PlatformEditionProvider editionProvider;

@@ -209,6 +210,14 @@ public class AnalysisMetadataHolderImpl implements MutableAnalysisMetadataHolder
return this;
}

@Override
public MutableAnalysisMetadataHolder setNewCodeReferenceBranch(String newCodeReferenceBranch) {
checkState(!this.newCodeReferenceBranch.isInitialized(), "newCodeReferenceBranch has already been set");
requireNonNull(newCodeReferenceBranch, "newCodeReferenceBranch can't be null");
this.newCodeReferenceBranch.setProperty(newCodeReferenceBranch);
return this;
}

@Override
public Optional<String> getScmRevision() {
if (!scmRevision.isInitialized()) {
@@ -217,6 +226,14 @@ public class AnalysisMetadataHolderImpl implements MutableAnalysisMetadataHolder
return Optional.ofNullable(scmRevision.getProperty());
}

@Override
public Optional<String> getNewCodeReferenceBranch() {
if (!newCodeReferenceBranch.isInitialized()) {
return Optional.empty();
}
return Optional.of(newCodeReferenceBranch.getProperty());
}

@Override
public boolean isBranch() {
checkState(this.branch.isInitialized(), BRANCH_NOT_SET);

+ 2
- 0
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/analysis/MutableAnalysisMetadataHolder.java View File

@@ -80,4 +80,6 @@ public interface MutableAnalysisMetadataHolder extends AnalysisMetadataHolder {
* @throws IllegalStateException if scm revision id has already been set
*/
MutableAnalysisMetadataHolder setScmRevision(String scmRevisionId);

MutableAnalysisMetadataHolder setNewCodeReferenceBranch(String newCodeReferenceBranch);
}

+ 26
- 9
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/LoadPeriodsStep.java View File

@@ -23,6 +23,9 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Optional;
import java.util.function.Supplier;
import org.sonar.api.utils.System2;
import org.sonar.ce.task.log.CeTaskMessages;
import org.sonar.ce.task.log.CeTaskMessages.Message;
import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder;
import org.sonar.ce.task.projectanalysis.component.TreeRootHolder;
import org.sonar.ce.task.projectanalysis.period.NewCodePeriodResolver;
@@ -34,7 +37,8 @@ import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.newcodeperiod.NewCodePeriodDao;
import org.sonar.db.newcodeperiod.NewCodePeriodDto;
import org.sonar.db.newcodeperiod.NewCodePeriodType;

import static org.sonar.db.newcodeperiod.NewCodePeriodType.REFERENCE_BRANCH;

/**
* Populates the {@link PeriodHolder}
@@ -52,15 +56,19 @@ public class LoadPeriodsStep implements ComputationStep {
private final PeriodHolderImpl periodsHolder;
private final DbClient dbClient;
private final NewCodePeriodResolver resolver;
private final CeTaskMessages ceTaskMessages;
private final System2 system2;

public LoadPeriodsStep(AnalysisMetadataHolder analysisMetadataHolder, NewCodePeriodDao newCodePeriodDao, TreeRootHolder treeRootHolder,
PeriodHolderImpl periodsHolder, DbClient dbClient, NewCodePeriodResolver resolver) {
PeriodHolderImpl periodsHolder, DbClient dbClient, NewCodePeriodResolver resolver, CeTaskMessages ceTaskMessages, System2 system2) {
this.analysisMetadataHolder = analysisMetadataHolder;
this.newCodePeriodDao = newCodePeriodDao;
this.treeRootHolder = treeRootHolder;
this.periodsHolder = periodsHolder;
this.dbClient = dbClient;
this.resolver = resolver;
this.ceTaskMessages = ceTaskMessages;
this.system2 = system2;
}

@Override
@@ -79,18 +87,27 @@ public class LoadPeriodsStep implements ComputationStep {
String branchUuid = treeRootHolder.getRoot().getUuid();
String projectVersion = treeRootHolder.getRoot().getProjectAttributes().getProjectVersion();

var newCodePeriod = analysisMetadataHolder.getNewCodeReferenceBranch()
.filter(s -> !s.isBlank())
.map(b -> new NewCodePeriodDto().setType(REFERENCE_BRANCH).setValue(b))
.orElse(null);

try (DbSession dbSession = dbClient.openSession(false)) {
Optional<NewCodePeriodDto> dto = firstPresent(Arrays.asList(
Optional<NewCodePeriodDto> specificSetting = firstPresent(Arrays.asList(
() -> getBranchSetting(dbSession, projectUuid, branchUuid),
() -> getProjectSetting(dbSession, projectUuid),
() -> getGlobalSetting(dbSession)
() -> getProjectSetting(dbSession, projectUuid)
));

NewCodePeriodDto newCodePeriod = dto.orElse(NewCodePeriodDto.defaultInstance());
if (newCodePeriod == null) {
newCodePeriod = specificSetting.or(() -> getGlobalSetting(dbSession)).orElse(NewCodePeriodDto.defaultInstance());

if (analysisMetadataHolder.isFirstAnalysis() && newCodePeriod.getType() != NewCodePeriodType.REFERENCE_BRANCH) {
periodsHolder.setPeriod(null);
return;
if (analysisMetadataHolder.isFirstAnalysis() && newCodePeriod.getType() != REFERENCE_BRANCH) {
periodsHolder.setPeriod(null);
return;
}
} else if (specificSetting.isPresent()) {
ceTaskMessages.add(new Message("A scanner parameter is defining a new code reference branch "
+ "but one is already defined specifically for the branch in the New Code Period settings", system2.now()));
}

Period period = resolver.resolve(dbSession, branchUuid, newCodePeriod, projectVersion);

+ 1
- 0
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStep.java View File

@@ -80,6 +80,7 @@ public class LoadReportAnalysisMetadataHolderStep implements ComputationStep {
analysisMetadata.setRootComponentRef(reportMetadata.getRootComponentRef());
analysisMetadata.setCrossProjectDuplicationEnabled(reportMetadata.getCrossProjectDuplicationActivated());
analysisMetadata.setScmRevision(reportMetadata.getScmRevisionId());
analysisMetadata.setNewCodeReferenceBranch(reportMetadata.getNewCodeReferenceBranch());
}

/**

+ 28
- 3
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/analysis/AnalysisMetadataHolderImplTest.java View File

@@ -49,7 +49,6 @@ public class AnalysisMetadataHolderImplTest {
.build();
private static final long SOME_DATE = 10000000L;


private final PlatformEditionProvider editionProvider = mock(PlatformEditionProvider.class);
private final AnalysisMetadataHolderImpl underTest = new AnalysisMetadataHolderImpl(editionProvider);

@@ -77,6 +76,32 @@ public class AnalysisMetadataHolderImplTest {
assertThat(underTest.getAnalysisDate()).isEqualTo(SOME_DATE);
}

@Test
public void get_new_code_reference_branch() {

String newCodeReferenceBranch = "newCodeReferenceBranch";
underTest.setNewCodeReferenceBranch(newCodeReferenceBranch);

assertThat(underTest.getNewCodeReferenceBranch()).hasValue(newCodeReferenceBranch);
}

@Test
public void get_new_code_reference_branch_return_empty_when_holder_is_not_initialized() {

assertThat(underTest.getNewCodeReferenceBranch()).isEmpty();
}

@Test
public void set_new_code_reference_branch_throws_ISE_when_called_twice() {

String newCodeReferenceBranch = "newCodeReferenceBranch";
underTest.setNewCodeReferenceBranch(newCodeReferenceBranch);

assertThatThrownBy(() -> underTest.setNewCodeReferenceBranch(newCodeReferenceBranch))
.isInstanceOf(IllegalStateException.class)
.hasMessage("newCodeReferenceBranch has already been set");
}

@Test
public void getAnalysisDate_throws_ISE_when_holder_is_not_initialized() {
assertThatThrownBy(() -> new AnalysisMetadataHolderImpl(editionProvider).getAnalysisDate())
@@ -338,7 +363,7 @@ public class AnalysisMetadataHolderImplTest {
AnalysisMetadataHolderImpl underTest = new AnalysisMetadataHolderImpl(editionProvider);
underTest.setRootComponentRef(10);

assertThatThrownBy(() -> underTest.setRootComponentRef(9))
assertThatThrownBy(() -> underTest.setRootComponentRef(9))
.isInstanceOf(IllegalStateException.class)
.hasMessage("Root component ref has already been set");
}
@@ -359,7 +384,7 @@ public class AnalysisMetadataHolderImplTest {
AnalysisMetadataHolderImpl underTest = new AnalysisMetadataHolderImpl(editionProvider);
underTest.setScmRevision("bd56dab");

assertThatThrownBy(() -> underTest.setScmRevision("bd56dab"))
assertThatThrownBy(() -> underTest.setScmRevision("bd56dab"))
.isInstanceOf(IllegalStateException.class)
.hasMessage("ScmRevision has already been set");
}

+ 61
- 8
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/LoadPeriodsStepTest.java View File

@@ -27,6 +27,7 @@ import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.Random;
import java.util.stream.Stream;
import javax.annotation.Nullable;
@@ -39,6 +40,7 @@ import org.sonar.api.utils.System2;
import org.sonar.api.utils.log.LogAndArguments;
import org.sonar.api.utils.log.LogTester;
import org.sonar.api.utils.log.LoggerLevel;
import org.sonar.ce.task.log.CeTaskMessages;
import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder;
import org.sonar.ce.task.projectanalysis.component.Component;
import org.sonar.ce.task.projectanalysis.component.ReportComponent;
@@ -62,8 +64,10 @@ import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import static org.sonar.db.component.SnapshotDto.STATUS_PROCESSED;
@@ -80,14 +84,15 @@ public class LoadPeriodsStepTest extends BaseStepTest {
@Rule
public LogTester logTester = new LogTester();

private AnalysisMetadataHolder analysisMetadataHolder = mock(AnalysisMetadataHolder.class);
private PeriodHolderImpl periodsHolder = new PeriodHolderImpl();
private System2 system2Mock = mock(System2.class);
private NewCodePeriodDao dao = new NewCodePeriodDao(system2Mock, new SequenceUuidFactory());
private NewCodePeriodResolver newCodePeriodResolver = new NewCodePeriodResolver(dbTester.getDbClient(), analysisMetadataHolder);
private ZonedDateTime analysisDate = ZonedDateTime.of(2019, 3, 20, 5, 30, 40, 0, ZoneId.systemDefault());

private LoadPeriodsStep underTest = new LoadPeriodsStep(analysisMetadataHolder, dao, treeRootHolder, periodsHolder, dbTester.getDbClient(), newCodePeriodResolver);
private final AnalysisMetadataHolder analysisMetadataHolder = mock(AnalysisMetadataHolder.class);
private final PeriodHolderImpl periodsHolder = new PeriodHolderImpl();
private final System2 system2Mock = mock(System2.class);
private final NewCodePeriodDao dao = new NewCodePeriodDao(system2Mock, new SequenceUuidFactory());
private final NewCodePeriodResolver newCodePeriodResolver = new NewCodePeriodResolver(dbTester.getDbClient(), analysisMetadataHolder);
private final ZonedDateTime analysisDate = ZonedDateTime.of(2019, 3, 20, 5, 30, 40, 0, ZoneId.systemDefault());
private final CeTaskMessages ceTaskMessages = mock(CeTaskMessages.class);
private final LoadPeriodsStep underTest = new LoadPeriodsStep(analysisMetadataHolder, dao, treeRootHolder, periodsHolder, dbTester.getDbClient(), newCodePeriodResolver,
ceTaskMessages, system2Mock);

private ComponentDto project;

@@ -115,6 +120,7 @@ public class LoadPeriodsStepTest extends BaseStepTest {
verify(analysisMetadataHolder).isFirstAnalysis();
verify(analysisMetadataHolder).isBranch();
verify(analysisMetadataHolder).getProject();
verify(analysisMetadataHolder).getNewCodeReferenceBranch();
assertThat(periodsHolder.hasPeriod()).isFalse();
verifyNoMoreInteractions(analysisMetadataHolder);
}
@@ -166,6 +172,7 @@ public class LoadPeriodsStepTest extends BaseStepTest {
setBranchPeriod(project.uuid(), branch.uuid(), NewCodePeriodType.NUMBER_OF_DAYS, "10");

testNumberOfDays(branch);
verifyNoInteractions(ceTaskMessages);
}

@Test
@@ -177,6 +184,50 @@ public class LoadPeriodsStepTest extends BaseStepTest {

underTest.execute(new TestComputationStepContext());
assertPeriod(NewCodePeriodType.REFERENCE_BRANCH, "master", null);
verifyNoInteractions(ceTaskMessages);
}

@Test
public void add_analysis_warning_if_scanner_defines_reference_when_branch_setting_also_defines_reference() {
ComponentDto branch = dbTester.components().insertProjectBranch(project);
setupRoot(branch);

setBranchPeriod(project.uuid(), branch.uuid(), NewCodePeriodType.REFERENCE_BRANCH, "master");

String newCodeReferenceBranch = "newCodeReferenceBranch";
when(analysisMetadataHolder.getNewCodeReferenceBranch()).thenReturn(Optional.of(newCodeReferenceBranch));

underTest.execute(new TestComputationStepContext());
assertPeriod(NewCodePeriodType.REFERENCE_BRANCH, newCodeReferenceBranch, null);
verify(ceTaskMessages).add(any(CeTaskMessages.Message.class));
}

@Test
public void scanner_defines_new_code_reference_branch() {
ComponentDto branch = dbTester.components().insertProjectBranch(project);
setupRoot(branch);

String newCodeReferenceBranch = "newCodeReferenceBranch";
when(analysisMetadataHolder.getNewCodeReferenceBranch()).thenReturn(Optional.of(newCodeReferenceBranch));

underTest.execute(new TestComputationStepContext());
assertPeriod(NewCodePeriodType.REFERENCE_BRANCH, newCodeReferenceBranch, null);
verifyNoInteractions(ceTaskMessages);
}

@Test
public void scanner_overrides_new_code_reference_branch() {
ComponentDto branch = dbTester.components().insertProjectBranch(project);
setupRoot(branch);

setProjectPeriod(project.uuid(), NewCodePeriodType.REFERENCE_BRANCH, "master");

String newCodeReferenceBranch = "newCodeReferenceBranch";
when(analysisMetadataHolder.getNewCodeReferenceBranch()).thenReturn(Optional.of(newCodeReferenceBranch));

underTest.execute(new TestComputationStepContext());
assertPeriod(NewCodePeriodType.REFERENCE_BRANCH, newCodeReferenceBranch, null);
verify(ceTaskMessages).add(any(CeTaskMessages.Message.class));
}

@Test
@@ -188,6 +239,7 @@ public class LoadPeriodsStepTest extends BaseStepTest {

underTest.execute(new TestComputationStepContext());
assertPeriod(NewCodePeriodType.REFERENCE_BRANCH, "master", null);
verifyNoInteractions(ceTaskMessages);
}

private void testNumberOfDays(ComponentDto projectOrBranch) {
@@ -217,6 +269,7 @@ public class LoadPeriodsStepTest extends BaseStepTest {

assertPeriod(NewCodePeriodType.SPECIFIC_ANALYSIS, selectedAnalysis.getUuid(), selectedAnalysis.getCreatedAt());
verifyDebugLogs("Resolving new code period with a specific analysis");
verifyNoInteractions(ceTaskMessages);
}

@Test

+ 13
- 0
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/LoadReportAnalysisMetadataHolderStepTest.java View File

@@ -103,6 +103,19 @@ public class LoadReportAnalysisMetadataHolderStepTest {
assertThat(analysisMetadataHolder.getAnalysisDate()).isEqualTo(ANALYSIS_DATE);
}

@Test
public void set_new_code_reference_branch() {
String newCodeReferenceBranch = "newCodeReferenceBranch";
reportReader.setMetadata(
newBatchReportBuilder()
.setNewCodeReferenceBranch(newCodeReferenceBranch)
.build());

underTest.execute(new TestComputationStepContext());

assertThat(analysisMetadataHolder.getNewCodeReferenceBranch()).hasValue(newCodeReferenceBranch);
}

@Test
public void set_project_from_dto() {
reportReader.setMetadata(

+ 16
- 0
server/sonar-ce-task-projectanalysis/src/testFixtures/java/org/sonar/ce/task/projectanalysis/analysis/AnalysisMetadataHolderRule.java View File

@@ -47,6 +47,7 @@ public class AnalysisMetadataHolderRule extends ExternalResource implements Muta
private final InitializedProperty<Map<String, QualityProfile>> qProfilesPerLanguage = new InitializedProperty<>();
private final InitializedProperty<Map<String, ScannerPlugin>> pluginsByKey = new InitializedProperty<>();
private final InitializedProperty<String> scmRevision = new InitializedProperty<>();
private final InitializedProperty<String> newCodeReferenceBranch = new InitializedProperty<>();

@Override
public AnalysisMetadataHolderRule setUuid(String s) {
@@ -193,6 +194,13 @@ public class AnalysisMetadataHolderRule extends ExternalResource implements Muta
return this;
}

@Override
public MutableAnalysisMetadataHolder setNewCodeReferenceBranch(String newCodeReferenceBranch) {
checkState(!this.newCodeReferenceBranch.isInitialized(), "ScmRevisionId has already been set");
this.newCodeReferenceBranch.setProperty(defaultIfBlank(newCodeReferenceBranch, null));
return this;
}

@Override
public Optional<String> getScmRevision() {
if (!scmRevision.isInitialized()) {
@@ -201,6 +209,14 @@ public class AnalysisMetadataHolderRule extends ExternalResource implements Muta
return Optional.ofNullable(scmRevision.getProperty());
}

@Override
public Optional<String> getNewCodeReferenceBranch() {
if (!newCodeReferenceBranch.isInitialized()) {
return Optional.empty();
}
return Optional.ofNullable(newCodeReferenceBranch.getProperty());
}

@Override
public boolean isBranch() {
Branch property = this.branch.getProperty();

+ 9
- 0
server/sonar-ce-task-projectanalysis/src/testFixtures/java/org/sonar/ce/task/projectanalysis/analysis/MutableAnalysisMetadataHolderRule.java View File

@@ -165,11 +165,20 @@ public class MutableAnalysisMetadataHolderRule extends ExternalResource implemen
return this;
}

@Override public MutableAnalysisMetadataHolder setNewCodeReferenceBranch(String newCodeReferenceBranch) {
delegate.setNewCodeReferenceBranch(newCodeReferenceBranch);
return this;
}

@Override
public Optional<String> getScmRevision() {
return delegate.getScmRevision();
}

@Override public Optional<String> getNewCodeReferenceBranch() {
return delegate.getNewCodeReferenceBranch();
}

@Override
public boolean isBranch() {
return delegate.isBranch();

Loading…
Cancel
Save