*/
package org.sonar.ce.task.projectanalysis.qualitygate;
+import java.util.Collection;
+import java.util.LinkedHashSet;
import java.util.Objects;
import java.util.Set;
import javax.annotation.concurrent.Immutable;
-import static com.google.common.base.Predicates.notNull;
-import static com.google.common.collect.FluentIterable.from;
+import static java.util.Collections.unmodifiableSet;
@Immutable
public class QualityGate {
private final String name;
private final Set<Condition> conditions;
- public QualityGate(String uuid, String name, Iterable<Condition> conditions) {
+ public QualityGate(String uuid, String name, Collection<Condition> conditions) {
this.uuid = uuid;
this.name = Objects.requireNonNull(name);
- this.conditions = from(conditions).filter(notNull()).toSet();
+ this.conditions = unmodifiableSet(new LinkedHashSet<>(conditions));
}
public String getUuid() {
*/
package org.sonar.ce.task.projectanalysis.qualitygate;
-import java.util.Optional;
import org.sonar.server.project.Project;
public interface QualityGateService {
-
- /**
- * Retrieve the {@link QualityGate} from the database with the specified uuid, if it exists.
- */
- Optional<QualityGate> findByUuid(String uuid);
-
/**
- * Retrieve the {@link QualityGate} from the database.
- * @throws IllegalStateException if database is corrupted and default gate can't be found.
+ * Retrieve the {@link QualityGate} from the database associated with project. If there's none, it returns the default quality gate.
*/
- QualityGate findDefaultQualityGate();
-
- /**
- * Retrieve the {@link QualityGate} from the database associated with project.
- */
- Optional<QualityGate> findQualityGate(Project project);
-
+ QualityGate findEffectiveQualityGate(Project project);
}
import org.sonar.ce.task.projectanalysis.metric.MetricRepository;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
-import org.sonar.db.property.PropertyDto;
import org.sonar.db.qualitygate.QualityGateConditionDto;
import org.sonar.db.qualitygate.QualityGateDto;
import org.sonar.server.project.Project;
import static org.sonar.core.util.stream.MoreCollectors.toList;
public class QualityGateServiceImpl implements QualityGateService {
- private static final String DEFAULT_QUALITY_GATE_PROPERTY_NAME = "qualitygate.default";
-
private final DbClient dbClient;
private final MetricRepository metricRepository;
}
@Override
- public Optional<QualityGate> findByUuid(String uuid) {
- try (DbSession dbSession = dbClient.openSession(false)) {
- QualityGateDto qualityGateDto = dbClient.qualityGateDao().selectByUuid(dbSession, uuid);
- if (qualityGateDto == null) {
- return Optional.empty();
- }
- return Optional.of(toQualityGate(dbSession, qualityGateDto));
- }
+ public QualityGate findEffectiveQualityGate(Project project) {
+ return findQualityGate(project).orElseGet(this::findDefaultQualityGate);
}
- @Override
- public QualityGate findDefaultQualityGate() {
+ private QualityGate findDefaultQualityGate() {
try (DbSession dbSession = dbClient.openSession(false)) {
- QualityGateDto qualityGateDto = getDefaultQualityGate(dbSession);
+ QualityGateDto qualityGateDto = dbClient.qualityGateDao().selectDefault(dbSession);
if (qualityGateDto == null) {
throw new IllegalStateException("The default Quality gate is missing");
}
}
}
- private QualityGateDto getDefaultQualityGate(DbSession dbSession) {
- PropertyDto propertyDto = Optional.ofNullable(dbClient.propertiesDao()
- .selectGlobalProperty(dbSession, DEFAULT_QUALITY_GATE_PROPERTY_NAME))
- .orElseThrow(() -> new IllegalStateException("The default Quality Gate property is missing"));
- return Optional.ofNullable(dbClient.qualityGateDao().selectByUuid(dbSession, propertyDto.getValue()))
- .orElseThrow(() -> new IllegalStateException("The default Quality gate is missing"));
- }
-
- @Override
- public Optional<QualityGate> findQualityGate(Project project) {
+ private Optional<QualityGate> findQualityGate(Project project) {
try (DbSession dbSession = dbClient.openSession(false)) {
- QualityGateDto qualityGateDto = dbClient.qualityGateDao().selectByProjectUuid(dbSession, project.getUuid());
- if (qualityGateDto == null) {
- return Optional.empty();
- }
- return Optional.of(toQualityGate(dbSession, qualityGateDto));
+ return Optional.ofNullable(dbClient.qualityGateDao().selectByProjectUuid(dbSession, project.getUuid()))
+ .map(qg -> toQualityGate(dbSession, qg));
}
}
private QualityGate toQualityGate(DbSession dbSession, QualityGateDto qualityGateDto) {
Collection<QualityGateConditionDto> dtos = dbClient.gateConditionDao().selectForQualityGate(dbSession, qualityGateDto.getUuid());
- Iterable<Condition> conditions = dtos.stream()
+ Collection<Condition> conditions = dtos.stream()
.map(input -> metricRepository.getOptionalByUuid(input.getMetricUuid())
.map(metric -> new Condition(metric, input.getOperator(), input.getErrorThreshold()))
.orElse(null))
*/
package org.sonar.ce.task.projectanalysis.step;
-import java.util.Optional;
import java.util.stream.Collectors;
import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolder;
import org.sonar.ce.task.projectanalysis.qualitygate.Condition;
private final MutableQualityGateHolder qualityGateHolder;
private final AnalysisMetadataHolder analysisMetadataHolder;
- public LoadQualityGateStep(QualityGateService qualityGateService, MutableQualityGateHolder qualityGateHolder,
- AnalysisMetadataHolder analysisMetadataHolder) {
+ public LoadQualityGateStep(QualityGateService qualityGateService, MutableQualityGateHolder qualityGateHolder, AnalysisMetadataHolder analysisMetadataHolder) {
this.qualityGateService = qualityGateService;
this.qualityGateHolder = qualityGateHolder;
this.analysisMetadataHolder = analysisMetadataHolder;
@Override
public void execute(ComputationStep.Context context) {
- Optional<QualityGate> qualityGate = getProjectQualityGate();
- if (!qualityGate.isPresent()) {
- // No QG defined for the project, let's retrieve the default QG
- qualityGate = Optional.of(getDefaultQualityGate());
- }
+ QualityGate qualityGate = getProjectQualityGate();
if (analysisMetadataHolder.isPullRequest()) {
qualityGate = filterQGForPR(qualityGate);
}
- qualityGateHolder.setQualityGate(qualityGate.orElseThrow(() -> new IllegalStateException("Quality gate not present")));
+ qualityGateHolder.setQualityGate(qualityGate);
}
- private static Optional<QualityGate> filterQGForPR(Optional<QualityGate> qualityGate) {
- return qualityGate.map(qg -> new QualityGate(qg.getUuid(), qg.getName(),
- qg.getConditions().stream().filter(Condition::useVariation).collect(Collectors.toList())));
+ private static QualityGate filterQGForPR(QualityGate qg) {
+ return new QualityGate(qg.getUuid(), qg.getName(), qg.getConditions().stream().filter(Condition::useVariation).collect(Collectors.toList()));
}
- private Optional<QualityGate> getProjectQualityGate() {
+ private QualityGate getProjectQualityGate() {
Project project = analysisMetadataHolder.getProject();
- return qualityGateService.findQualityGate(project);
- }
-
- private QualityGate getDefaultQualityGate() {
- return qualityGateService.findDefaultQualityGate();
+ return qualityGateService.findEffectiveQualityGate(project);
}
@Override
private final QualityGateDao qualityGateDao = mock(QualityGateDao.class);
private final QualityGateConditionDao qualityGateConditionDao = mock(QualityGateConditionDao.class);
- private final PropertiesDao propertiesDao = mock(PropertiesDao.class);
private final MetricRepository metricRepository = mock(MetricRepository.class);
private final DbClient dbClient = mock(DbClient.class);
- private final QualityGateServiceImpl underTest = new QualityGateServiceImpl(dbClient, metricRepository);
+ private final QualityGateService underTest = new QualityGateServiceImpl(dbClient, metricRepository);
@Before
public void setUp() {
when(dbClient.qualityGateDao()).thenReturn(qualityGateDao);
when(dbClient.gateConditionDao()).thenReturn(qualityGateConditionDao);
- when(dbClient.propertiesDao()).thenReturn(propertiesDao);
when(METRIC_1.getKey()).thenReturn("metric");
when(METRIC_2.getKey()).thenReturn("new_metric");
}
- @Test
- public void findById_returns_absent_when_QualityGateDto_does_not_exist() {
- assertThat(underTest.findByUuid(SOME_UUID)).isNotPresent();
- }
-
- @Test
- public void findById_returns_QualityGate_with_empty_set_of_conditions_when_there_is_none_in_DB() {
- when(qualityGateDao.selectByUuid(any(), eq(SOME_UUID))).thenReturn(QUALITY_GATE_DTO);
- when(qualityGateConditionDao.selectForQualityGate(any(), eq(SOME_UUID))).thenReturn(Collections.emptyList());
-
- Optional<QualityGate> res = underTest.findByUuid(SOME_UUID);
-
- assertThat(res).isPresent();
- assertThat(res.get().getUuid()).isEqualTo(SOME_UUID);
- assertThat(res.get().getName()).isEqualTo(SOME_NAME);
- assertThat(res.get().getConditions()).isEmpty();
- }
-
- @Test
- public void findById_returns_conditions_when_there_is_some_in_DB() {
- when(qualityGateDao.selectByUuid(any(), eq(SOME_UUID))).thenReturn(QUALITY_GATE_DTO);
- when(qualityGateConditionDao.selectForQualityGate(any(), eq(SOME_UUID))).thenReturn(ImmutableList.of(CONDITION_1, CONDITION_2));
- // metrics are always supposed to be there
- when(metricRepository.getOptionalByUuid(METRIC_UUID_1)).thenReturn(Optional.of(METRIC_1));
- when(metricRepository.getOptionalByUuid(METRIC_UUID_2)).thenReturn(Optional.of(METRIC_2));
-
- Optional<QualityGate> res = underTest.findByUuid(SOME_UUID);
-
- assertThat(res).isPresent();
- assertThat(res.get().getUuid()).isEqualTo(SOME_UUID);
- assertThat(res.get().getName()).isEqualTo(SOME_NAME);
- assertThat(res.get().getConditions()).containsOnly(
- new Condition(METRIC_1, CONDITION_1.getOperator(), CONDITION_1.getErrorThreshold()),
- new Condition(METRIC_2, CONDITION_2.getOperator(), CONDITION_2.getErrorThreshold()));
- }
-
- @Test
- public void findById_ignores_conditions_on_missing_metrics() {
- when(qualityGateDao.selectByUuid(any(), eq(SOME_UUID))).thenReturn(QUALITY_GATE_DTO);
- when(qualityGateConditionDao.selectForQualityGate(any(), eq(SOME_UUID))).thenReturn(ImmutableList.of(CONDITION_1, CONDITION_2));
- // metrics are always supposed to be there
- when(metricRepository.getOptionalByUuid(METRIC_UUID_1)).thenReturn(Optional.empty());
- when(metricRepository.getOptionalByUuid(METRIC_UUID_2)).thenReturn(Optional.of(METRIC_2));
-
- Optional<QualityGate> res = underTest.findByUuid(SOME_UUID);
-
- assertThat(res).isPresent();
- assertThat(res.get().getUuid()).isEqualTo(SOME_UUID);
- assertThat(res.get().getName()).isEqualTo(SOME_NAME);
- assertThat(res.get().getConditions()).containsOnly(
- new Condition(METRIC_2, CONDITION_2.getOperator(), CONDITION_2.getErrorThreshold()));
- }
-
@Test
public void findDefaultQualityGate_by_property_not_found() {
- when(propertiesDao.selectGlobalProperty(any(), any())).thenReturn(null);
-
- assertThatThrownBy(() -> underTest.findDefaultQualityGate())
- .isInstanceOf(IllegalStateException.class);
+ assertThatThrownBy(() -> underTest.findEffectiveQualityGate(mock(Project.class))).isInstanceOf(IllegalStateException.class);
}
@Test
QualityGateDto qualityGateDto = new QualityGateDto();
qualityGateDto.setUuid(QUALITY_GATE_DTO.getUuid());
qualityGateDto.setName(QUALITY_GATE_DTO.getName());
- when(propertiesDao.selectGlobalProperty(any(), any())).thenReturn(new PropertyDto().setValue(QUALITY_GATE_DTO.getUuid()));
- when(qualityGateDao.selectByUuid(any(), any())).thenReturn(qualityGateDto);
+ when(qualityGateDao.selectDefault(any())).thenReturn(qualityGateDto);
when(qualityGateConditionDao.selectForQualityGate(any(), eq(SOME_UUID))).thenReturn(ImmutableList.of(CONDITION_1, CONDITION_2));
when(metricRepository.getOptionalByUuid(METRIC_UUID_1)).thenReturn(Optional.empty());
when(metricRepository.getOptionalByUuid(METRIC_UUID_2)).thenReturn(Optional.of(METRIC_2));
- QualityGate result = underTest.findDefaultQualityGate();
+ QualityGate result = underTest.findEffectiveQualityGate(mock(Project.class));
assertThat(result).isNotNull();
assertThat(result.getUuid()).isEqualTo(QUALITY_GATE_DTO.getUuid());
- assertThat(result.getName()).isNotBlank();
assertThat(result.getName()).isEqualTo(QUALITY_GATE_DTO.getName());
}
- @Test
- public void findQualityGate_by_project_not_found() {
- when(qualityGateDao.selectByProjectUuid(any(), any())).thenReturn(null);
- Optional<QualityGate> result = underTest.findQualityGate(mock(Project.class));
- assertThat(result).isEmpty();
- }
-
@Test
public void findQualityGate_by_project_found() {
QualityGateDto qualityGateDto = new QualityGateDto();
qualityGateDto.setUuid(QUALITY_GATE_DTO.getUuid());
qualityGateDto.setName(QUALITY_GATE_DTO.getName());
+
when(qualityGateDao.selectByProjectUuid(any(), any())).thenReturn(qualityGateDto);
when(qualityGateConditionDao.selectForQualityGate(any(), eq(SOME_UUID))).thenReturn(ImmutableList.of(CONDITION_1, CONDITION_2));
when(metricRepository.getOptionalByUuid(METRIC_UUID_1)).thenReturn(Optional.empty());
when(metricRepository.getOptionalByUuid(METRIC_UUID_2)).thenReturn(Optional.of(METRIC_2));
- Optional<QualityGate> result = underTest.findQualityGate(mock(Project.class));
+ QualityGate result = underTest.findEffectiveQualityGate(mock(Project.class));
- assertThat(result).isNotNull();
- assertThat(result).isNotEmpty();
-
- QualityGate resultData = result.get();
- assertThat(resultData.getUuid()).isEqualTo(QUALITY_GATE_DTO.getUuid());
- assertThat(resultData.getName()).isNotBlank();
- assertThat(resultData.getName()).isEqualTo(QUALITY_GATE_DTO.getName());
+ assertThat(result.getUuid()).isEqualTo(QUALITY_GATE_DTO.getUuid());
+ assertThat(result.getName()).isEqualTo(QUALITY_GATE_DTO.getName());
}
}
package org.sonar.ce.task.projectanalysis.step;
import java.util.Arrays;
-import java.util.Optional;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.ce.task.projectanalysis.qualitygate.Condition;
import org.sonar.ce.task.projectanalysis.qualitygate.MutableQualityGateHolderRule;
import org.sonar.ce.task.projectanalysis.qualitygate.QualityGate;
-import org.sonar.ce.task.projectanalysis.qualitygate.QualityGateService;
+import org.sonar.ce.task.projectanalysis.qualitygate.QualityGateServiceImpl;
import org.sonar.ce.task.step.TestComputationStepContext;
import org.sonar.server.project.Project;
-import static java.util.Collections.emptyList;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class LoadQualityGateStepTest {
-
@Rule
public MutableQualityGateHolderRule mutableQualityGateHolder = new MutableQualityGateHolderRule();
private final AnalysisMetadataHolder analysisMetadataHolder = mock(AnalysisMetadataHolder.class);
- private final QualityGateService qualityGateService = mock(QualityGateService.class);
+ private final QualityGateServiceImpl qualityGateService = mock(QualityGateServiceImpl.class);
private final LoadQualityGateStep underTest = new LoadQualityGateStep(qualityGateService, mutableQualityGateHolder, analysisMetadataHolder);
+ private final Project project = mock(Project.class);
@Before
- public void setUp() {
+ public void before() {
+ when(analysisMetadataHolder.getProject()).thenReturn(project);
}
@Test
when(analysisMetadataHolder.isPullRequest()).thenReturn(true);
QualityGate defaultGate = new QualityGate("1", "qg", Arrays.asList(variation, condition));
- when(qualityGateService.findDefaultQualityGate()).thenReturn(defaultGate);
+ when(qualityGateService.findEffectiveQualityGate(project)).thenReturn(defaultGate);
underTest.execute(new TestComputationStepContext());
}
@Test
- public void execute_sets_default_QualityGate_when_project_has_no_settings() {
- QualityGate defaultGate = mock(QualityGate.class);
- when(qualityGateService.findDefaultQualityGate()).thenReturn(defaultGate);
+ public void execute_sets_effective_quality_gate() {
+ QualityGate qg = mock(QualityGate.class);
+ when(qualityGateService.findEffectiveQualityGate(project)).thenReturn(qg);
underTest.execute(new TestComputationStepContext());
- assertThat(mutableQualityGateHolder.getQualityGate().get()).isSameAs(defaultGate);
+ assertThat(mutableQualityGateHolder.getQualityGate()).containsSame(qg);
}
-
- @Test
- public void execute_sets_QualityGate_if_it_can_be_found_by_service() {
- QualityGate qualityGate = new QualityGate("10", "name", emptyList());
-
- when(analysisMetadataHolder.getProject()).thenReturn(mock(Project.class));
- when(qualityGateService.findQualityGate(any(Project.class))).thenReturn(Optional.of(qualityGate));
-
- underTest.execute(new TestComputationStepContext());
-
- assertThat(mutableQualityGateHolder.getQualityGate().get()).isSameAs(qualityGate);
- }
-
}
componentUuids -> mapper(dbSession).selectByComponentUuidsAndMetricUuids(componentUuids, metricUuis));
}
- public void scrollSelectByComponentUuidAndMetricKeys(DbSession dbSession, String componentUuid, Collection<String> metricKeys,
- ResultHandler<LiveMeasureDto> handler) {
+ public void scrollSelectByComponentUuidAndMetricKeys(DbSession dbSession, String componentUuid, Collection<String> metricKeys, ResultHandler<LiveMeasureDto> handler) {
if (metricKeys.isEmpty()) {
return;
}
return mapper(session).selectByUuid(uuid);
}
+ @CheckForNull
+ public QualityGateDto selectDefault(DbSession session) {
+ return mapper(session).selectDefault();
+ }
+
public void delete(QualityGateDto qGate, DbSession session) {
mapper(session).delete(qGate.getUuid());
}
return session.getMapper(QualityGateMapper.class);
}
+ @CheckForNull
public QualityGateDto selectByProjectUuid(DbSession dbSession, String projectUuid) {
return mapper(dbSession).selectByProjectUuid(projectUuid);
}
QualityGateDto selectByUuid(String uuid);
+ QualityGateDto selectDefault();
+
QualityGateDto selectByProjectUuid(@Param("projectUuid") String projectUuid);
}
return mapper(dbSession).selectAssociatedToProjectUuidAndLanguage(project.getUuid(), language);
}
- public List<QProfileDto> selectAssociatedToProjectUuidAndLanguages(DbSession dbSession, ProjectDto project, Collection<String> languages) {
- return executeLargeInputs(languages, partition -> mapper(dbSession).selectAssociatedToProjectUuidAndLanguages(project.getUuid(), partition));
+ public List<QProfileDto> selectAssociatedToProjectUuidAndLanguages(DbSession dbSession, String projectUuid, Collection<String> languages) {
+ return executeLargeInputs(languages, partition -> mapper(dbSession).selectAssociatedToProjectUuidAndLanguages(projectUuid, partition));
+ }
+
+ public List<QProfileDto> selectAssociatedToProjectAndLanguages(DbSession dbSession, ProjectDto project, Collection<String> languages) {
+ return selectAssociatedToProjectUuidAndLanguages(dbSession, project.getUuid(), languages);
}
public List<QProfileDto> selectByLanguage(DbSession dbSession, String language) {
<mapper namespace="org.sonar.db.qualitygate.QualityGateMapper">
<sql id="gateColumns">
- uuid, name, is_built_in as isBuiltIn, created_at as createdAt, updated_at as updatedAt
+ qg.uuid, qg.name, qg.is_built_in as isBuiltIn, qg.created_at as createdAt, qg.updated_at as updatedAt
</sql>
<insert id="insertQualityGate" parameterType="QualityGate" useGeneratedKeys="false">
<select id="selectByName" parameterType="String" resultType="QualityGate">
select
<include refid="gateColumns"/>
- from quality_gates
+ from quality_gates qg
where name=#{name, jdbcType=VARCHAR}
</select>
<select id="selectByUuid" parameterType="String" resultType="QualityGate">
select
<include refid="gateColumns"/>
- from quality_gates
+ from quality_gates qg
where uuid=#{uuid, jdbcType=VARCHAR}
</select>
<select id="selectBuiltIn" resultType="org.sonar.db.qualitygate.QualityGateDto">
SELECT
<include refid="gateColumns"/>
- FROM quality_gates
+ FROM quality_gates qg
WHERE
is_built_in = ${_true}
</select>
+ <select id="selectDefault" resultType="org.sonar.db.qualitygate.QualityGateDto">
+ SELECT
+ <include refid="gateColumns"/>
+ FROM quality_gates qg INNER JOIN properties p ON qg.uuid = p.text_value
+ WHERE
+ p.prop_key = 'qualitygate.default'
+ and p.component_uuid is null
+ and p.user_uuid is null
+ </select>
+
<update id="delete" parameterType="String">
delete from quality_gates where uuid=#{uuid}
</update>
QProfileDto jsProfile = db.qualityProfiles().insert(p -> p.setLanguage("js"));
db.qualityProfiles().associateWithProject(project1, javaProfile, jsProfile);
- assertThat(underTest.selectAssociatedToProjectUuidAndLanguages(dbSession, project1, singletonList("java")))
+ assertThat(underTest.selectAssociatedToProjectAndLanguages(dbSession, project1, singletonList("java")))
.extracting(QProfileDto::getKee).containsOnly(javaProfile.getKee());
- assertThat(underTest.selectAssociatedToProjectUuidAndLanguages(dbSession, project1, singletonList("unknown")))
+ assertThat(underTest.selectAssociatedToProjectAndLanguages(dbSession, project1, singletonList("unknown")))
.isEmpty();
- assertThat(underTest.selectAssociatedToProjectUuidAndLanguages(dbSession, project1, of("java", "unknown")))
+ assertThat(underTest.selectAssociatedToProjectAndLanguages(dbSession, project1, of("java", "unknown")))
.extracting(QProfileDto::getKee).containsExactly(javaProfile.getKee());
- assertThat(underTest.selectAssociatedToProjectUuidAndLanguages(dbSession, project1, of("java", "js")))
+ assertThat(underTest.selectAssociatedToProjectAndLanguages(dbSession, project1, of("java", "js")))
.extracting(QProfileDto::getKee).containsExactlyInAnyOrder(javaProfile.getKee(), jsProfile.getKee());
- assertThat(underTest.selectAssociatedToProjectUuidAndLanguages(dbSession, project2, singletonList("java")))
+ assertThat(underTest.selectAssociatedToProjectAndLanguages(dbSession, project2, singletonList("java")))
.isEmpty();
- assertThat(underTest.selectAssociatedToProjectUuidAndLanguages(dbSession, project2, Collections.emptyList()))
+ assertThat(underTest.selectAssociatedToProjectAndLanguages(dbSession, project2, Collections.emptyList()))
.isEmpty();
}
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.project.ProjectDto;
-import org.sonar.db.property.PropertyDto;
import org.sonar.db.qualitygate.QualityGateDto;
-import static com.google.common.base.Preconditions.checkState;
-
public class QualityGateFinder {
- private static final String DEFAULT_QUALITY_GATE_PROPERTY_NAME = "qualitygate.default";
-
private final DbClient dbClient;
public QualityGateFinder(DbClient dbClient) {
this.dbClient = dbClient;
}
- public QualityGateData getQualityGate(DbSession dbSession, ProjectDto projectDto) {
- return getQualityGate(dbSession, projectDto.getUuid());
+ public QualityGateData getEffectiveQualityGate(DbSession dbSession, ProjectDto projectDto) {
+ return getEffectiveQualityGate(dbSession, projectDto.getUuid());
}
- public QualityGateData getQualityGate(DbSession dbSession, String projectUuid) {
+ public QualityGateData getEffectiveQualityGate(DbSession dbSession, String projectUuid) {
Optional<QualityGateData> res = getQualityGateForProject(dbSession, projectUuid);
if (res.isPresent()) {
return res.get();
}
public QualityGateDto getDefault(DbSession dbSession) {
- PropertyDto qGateDefaultUuidProperty = dbClient.propertiesDao().selectGlobalProperty(dbSession, DEFAULT_QUALITY_GATE_PROPERTY_NAME);
- checkState(qGateDefaultUuidProperty != null, "Default quality gate property is missing");
- dbClient.qualityGateDao().selectByUuid(dbSession, qGateDefaultUuidProperty.getValue());
- return Optional.ofNullable(dbClient.qualityGateDao().selectByUuid(dbSession, qGateDefaultUuidProperty.getValue()))
- .orElseThrow(() -> new IllegalStateException("Default quality gate is missing"));
- }
-
- public QualityGateDto getBuiltInQualityGate(DbSession dbSession) {
- QualityGateDto builtIn = dbClient.qualityGateDao().selectBuiltIn(dbSession);
- checkState(builtIn != null, "Builtin quality gate is missing.");
- return builtIn;
+ return Optional.ofNullable(dbClient.qualityGateDao().selectDefault(dbSession)).orElseThrow(() -> new IllegalStateException("Default quality gate is missing"));
}
public static class QualityGateData {
- private final QualityGateDto qualityGate;
+ private final String uuid;
+ private final String name;
private final boolean isDefault;
+ private final boolean builtIn;
private QualityGateData(QualityGateDto qualityGate, boolean isDefault) {
- this.qualityGate = qualityGate;
+ this.uuid = qualityGate.getUuid();
+ this.name = qualityGate.getName();
this.isDefault = isDefault;
+ this.builtIn = qualityGate.isBuiltIn();
+ }
+
+ public boolean isBuiltIn() {
+ return builtIn;
+ }
+
+ public String getUuid() {
+ return uuid;
}
- public QualityGateDto getQualityGate() {
- return qualityGate;
+ public String getName() {
+ return name;
}
public boolean isDefault() {
ProjectDto project = db.components().insertPrivateProjectDto();
QualityGateDto dbQualityGate = db.qualityGates().createDefaultQualityGate(qg -> qg.setName("Sonar way"));
- QualityGateFinder.QualityGateData result = underTest.getQualityGate(dbSession, project);
+ QualityGateFinder.QualityGateData result = underTest.getEffectiveQualityGate(dbSession, project);
- assertThat(result.getQualityGate().getUuid()).isEqualTo(dbQualityGate.getUuid());
+ assertThat(result.getUuid()).isEqualTo(dbQualityGate.getUuid());
assertThat(result.isDefault()).isTrue();
}
QualityGateDto dbQualityGate = db.qualityGates().insertQualityGate(qg -> qg.setName("My team QG"));
db.qualityGates().associateProjectToQualityGate(project, dbQualityGate);
- QualityGateFinder.QualityGateData result = underTest.getQualityGate(dbSession, project);
+ QualityGateFinder.QualityGateData result = underTest.getEffectiveQualityGate(dbSession, project);
- assertThat(result.getQualityGate().getUuid()).isEqualTo(dbQualityGate.getUuid());
+ assertThat(result.getUuid()).isEqualTo(dbQualityGate.getUuid());
assertThat(result.isDefault()).isFalse();
}
db.getDbClient().qualityGateDao().delete(dbQualityGate, dbSession);
db.commit();
- assertThatThrownBy(() -> underTest.getQualityGate(dbSession, project))
+ assertThatThrownBy(() -> underTest.getEffectiveQualityGate(dbSession, project))
.isInstanceOf(IllegalStateException.class)
.hasMessage("Default quality gate is missing");
}
db.qualityGates().associateProjectToQualityGate(project, dbQualityGate);
db.getDbClient().qualityGateDao().delete(dbQualityGate, dbSession);
- assertThatThrownBy(() -> underTest.getQualityGate(dbSession, project))
+ assertThatThrownBy(() -> underTest.getEffectiveQualityGate(dbSession, project))
.isInstanceOf(IllegalStateException.class)
.hasMessage("Default quality gate is missing");
}
QualityGateDto dbQualityGate = db.qualityGates().insertQualityGate(qg -> qg.setName("My team QG"));
db.getDbClient().qualityGateDao().delete(dbQualityGate, dbSession);
- assertThatThrownBy(() -> underTest.getQualityGate(dbSession, project))
+ assertThatThrownBy(() -> underTest.getEffectiveQualityGate(dbSession, project))
.isInstanceOf(IllegalStateException.class)
- .hasMessage("Default quality gate property is missing");
+ .hasMessage("Default quality gate is missing");
}
@Test
import org.sonar.db.metric.MetricDto;
import org.sonar.db.project.ProjectDto;
import org.sonar.db.qualitygate.QualityGateConditionDto;
-import org.sonar.db.qualitygate.QualityGateDto;
import org.sonar.server.qualitygate.Condition;
import org.sonar.server.qualitygate.EvaluatedQualityGate;
import org.sonar.server.qualitygate.QualityGate;
import org.sonar.server.qualitygate.QualityGateConverter;
import org.sonar.server.qualitygate.QualityGateEvaluator;
import org.sonar.server.qualitygate.QualityGateFinder;
+import org.sonar.server.qualitygate.QualityGateFinder.QualityGateData;
import static org.sonar.core.util.stream.MoreCollectors.toHashSet;
import static org.sonar.core.util.stream.MoreCollectors.uniqueIndex;
@Override
public QualityGate loadQualityGate(DbSession dbSession, ProjectDto project, BranchDto branch) {
- QualityGateDto gateDto = qGateFinder.getQualityGate(dbSession, project)
- .getQualityGate();
- Collection<QualityGateConditionDto> conditionDtos = dbClient.gateConditionDao().selectForQualityGate(dbSession, gateDto.getUuid());
+ QualityGateData qg = qGateFinder.getEffectiveQualityGate(dbSession, project);
+ Collection<QualityGateConditionDto> conditionDtos = dbClient.gateConditionDao().selectForQualityGate(dbSession, qg.getUuid());
Set<String> metricUuids = conditionDtos.stream().map(QualityGateConditionDto::getMetricUuid)
.collect(toHashSet(conditionDtos.size()));
Map<String, MetricDto> metricsByUuid = dbClient.metricDao().selectByUuids(dbSession, metricUuids).stream()
conditions = conditions.filter(Condition::isOnLeakPeriod);
}
- return new QualityGate(String.valueOf(gateDto.getUuid()), gateDto.getName(), conditions.collect(toHashSet(conditionDtos.size())));
+ return new QualityGate(String.valueOf(qg.getUuid()), qg.getName(), conditions.collect(toHashSet(conditionDtos.size())));
}
@Override
throw insufficientPrivilegesException();
}
- QualityGateData data = qualityGateFinder.getQualityGate(dbSession, project);
+ QualityGateData data = qualityGateFinder.getEffectiveQualityGate(dbSession, project);
writeProtobuf(buildResponse(data), request, response);
}
}
- private static GetByProjectResponse buildResponse(QualityGateData data) {
- QualityGateDto qualityGate = data.getQualityGate();
+ private static GetByProjectResponse buildResponse(QualityGateData qg) {
GetByProjectResponse.Builder response = GetByProjectResponse.newBuilder();
response.getQualityGateBuilder()
- .setId(qualityGate.getUuid())
- .setName(qualityGate.getName())
- .setDefault(data.isDefault());
+ .setId(qg.getUuid())
+ .setName(qg.getName())
+ .setDefault(qg.isDefault());
return response.build();
}
return p -> true;
}
Map<String, QProfileDto> effectiveProfiles = defaultProfiles.stream().collect(Collectors.toMap(QProfileDto::getLanguage, identity()));
- effectiveProfiles.putAll(dbClient.qualityProfileDao().selectAssociatedToProjectUuidAndLanguages(dbSession, project, getLanguageKeys()).stream()
+ effectiveProfiles.putAll(dbClient.qualityProfileDao().selectAssociatedToProjectAndLanguages(dbSession, project, getLanguageKeys()).stream()
.collect(MoreCollectors.uniqueIndex(QProfileDto::getLanguage)));
return p -> Objects.equals(p.getKee(), effectiveProfiles.get(p.getLanguage()).getKee());
}
}
private void writeQualityGate(JsonWriter json, DbSession session, ComponentDto component) {
- QualityGateFinder.QualityGateData qualityGateData = qualityGateFinder.getQualityGate(session, component.uuid());
- QualityGateDto qualityGateDto = qualityGateData.getQualityGate();
+ var qualityGateData = qualityGateFinder.getEffectiveQualityGate(session, component.uuid());
json.name("qualityGate").beginObject()
- .prop("key", qualityGateDto.getUuid())
- .prop("name", qualityGateDto.getName())
+ .prop("key", qualityGateData.getUuid())
+ .prop("name", qualityGateData.getName())
.prop("isDefault", qualityGateData.isDefault())
.endObject();
}
logTester.logs(LoggerLevel.INFO).contains("Built-in quality gate's conditions of [Sonar way] has been updated")).isTrue();
}
- @Test
- public void ensure_only_that_builtin_is_set_as_default_when_no_default_quality_gate() {
- insertMetrics();
- QualityGateDto builtInQualityGate = db.qualityGates().insertBuiltInQualityGate();
-
- underTest.start();
-
- assertThat(qualityGateFinder.getBuiltInQualityGate(dbSession)).isNotNull();
- assertThat(qualityGateFinder.getBuiltInQualityGate(dbSession).getUuid()).isEqualTo(builtInQualityGate.getUuid());
- }
-
@Test
public void builtin_quality_gate_with_incorrect_metricuuid_should_not_throw_an_exception() {
insertMetrics();