Browse Source

SONAR-6620 current project can actually have no QualityGate at all

in which case, no QualityGate measure must be created nor any measure have its QualityGateStatus be updated
tags/5.2-RC1
Sébastien Lesaint 9 years ago
parent
commit
0c18ea4d3f

+ 8
- 1
server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/MutableQualityGateHolder.java View File

@@ -30,7 +30,14 @@ public interface MutableQualityGateHolder extends QualityGateHolder {
* @param qualityGate a {@link Component}, can not be {@code null}
*
* @throws NullPointerException if {@code qualityGate} is {@code null}
* @throws IllegalStateException if the quality gate has already been set
* @throws IllegalStateException if the holder has already been initialized
*/
void setQualityGate(QualityGate qualityGate);

/**
* Sets that there is no quality gate for the project of the currently processed {@link ReportQueue.Item}.
*
* @throws IllegalStateException if the holder has already been initialized
*/
void setNoQualityGate();
}

+ 4
- 3
server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/QualityGateHolder.java View File

@@ -19,13 +19,14 @@
*/
package org.sonar.server.computation.qualitygate;

import com.google.common.base.Optional;
import org.sonar.server.computation.ReportQueue;

public interface QualityGateHolder {
/**
* The QualityGate for the project of the current {@link ReportQueue.Item}.
* The QualityGate for the project of the current {@link ReportQueue.Item} if there is any.
*
* @throws IllegalStateException if the holder is empty (ie. there is no quality gate yet)
* @throws IllegalStateException if the holder has not been initialized (ie. we don't know yet what is the QualityGate)
*/
QualityGate getQualityGate();
Optional<QualityGate> getQualityGate();
}

+ 26
- 11
server/sonar-server/src/main/java/org/sonar/server/computation/qualitygate/QualityGateHolderImpl.java View File

@@ -19,29 +19,44 @@
*/
package org.sonar.server.computation.qualitygate;

import java.util.Objects;
import com.google.common.base.Optional;
import javax.annotation.CheckForNull;

import static com.google.common.base.Optional.absent;
import static com.google.common.base.Optional.of;
import static com.google.common.base.Preconditions.checkState;
import static java.util.Objects.requireNonNull;

public class QualityGateHolderImpl implements MutableQualityGateHolder {
private boolean initialized = false;
@CheckForNull
private QualityGate qualityGate;
private Optional<QualityGate> qualityGate;

@Override
public void setQualityGate(QualityGate qualityGate) {
// fail fast
Objects.requireNonNull(qualityGate);
requireNonNull(qualityGate);
checkNotInitialized();

this.initialized = true;
this.qualityGate = of(qualityGate);
}

@Override
public void setNoQualityGate() {
checkNotInitialized();

this.initialized = true;
this.qualityGate = absent();
}

if (this.qualityGate != null) {
throw new IllegalStateException("QualityGate can be set only once");
}
this.qualityGate = qualityGate;
private void checkNotInitialized() {
checkState(!initialized, "QualityGateHolder can be initialized only once");
}

@Override
public QualityGate getQualityGate() {
if (qualityGate == null) {
throw new IllegalStateException("QualityGate has not been set yet");
}
public Optional<QualityGate> getQualityGate() {
checkState(initialized, "QualityGate has not been set yet");
return qualityGate;
}
}

+ 13
- 8
server/sonar-server/src/main/java/org/sonar/server/computation/step/QualityGateLoadingStep.java View File

@@ -19,7 +19,7 @@
*/
package org.sonar.server.computation.step;

import java.util.Collections;
import com.google.common.base.Optional;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.config.Settings;
import org.sonar.api.utils.log.Logger;
@@ -29,7 +29,6 @@ import org.sonar.server.computation.component.Component;
import org.sonar.server.computation.component.DepthTraversalTypeAwareVisitor;
import org.sonar.server.computation.component.ProjectSettingsRepository;
import org.sonar.server.computation.component.TreeRootHolder;
import org.sonar.server.computation.qualitygate.Condition;
import org.sonar.server.computation.qualitygate.MutableQualityGateHolder;
import org.sonar.server.computation.qualitygate.QualityGate;
import org.sonar.server.computation.qualitygate.QualityGateService;
@@ -45,7 +44,6 @@ public class QualityGateLoadingStep implements ComputationStep {
private static final Logger LOGGER = Loggers.get(QualityGateLoadingStep.class);

private static final String PROPERTY_QUALITY_GATE = "sonar.qualitygate";
private static final QualityGate DEFAULT_QUALITY_GATE = new QualityGate("default Quality Gate", Collections.<Condition>emptyList());

private final TreeRootHolder treeRootHolder;
private final ProjectSettingsRepository projectSettingsRepository;
@@ -77,16 +75,23 @@ public class QualityGateLoadingStep implements ComputationStep {

if (qualityGateSetting == null || StringUtils.isBlank(qualityGateSetting)) {
LOGGER.debug("No quality gate is configured for project " + projectKey);
qualityGateHolder.setQualityGate(DEFAULT_QUALITY_GATE);
qualityGateHolder.setNoQualityGate();
return;
}

try {
long qualityGateId = Long.parseLong(qualityGateSetting.trim());
qualityGateHolder.setQualityGate(qualityGateService.findById(qualityGateId).or(DEFAULT_QUALITY_GATE));
long qualityGateId = Long.parseLong(qualityGateSetting);
Optional<QualityGate> qualityGate = qualityGateService.findById(qualityGateId);
if (qualityGate.isPresent()) {
qualityGateHolder.setQualityGate(qualityGate.get());
}
else {
qualityGateHolder.setNoQualityGate();
}
} catch (NumberFormatException e) {
LOGGER.error(String.format("Unsupported value in property %s, using empty Quality Gate", PROPERTY_QUALITY_GATE));
qualityGateHolder.setQualityGate(DEFAULT_QUALITY_GATE);
throw new IllegalStateException(
String.format("Unsupported value (%s) in property %s", qualityGateSetting, PROPERTY_QUALITY_GATE),
e);
}
}


+ 6
- 2
server/sonar-server/src/main/java/org/sonar/server/computation/step/QualityGateMeasuresStep.java View File

@@ -40,6 +40,7 @@ import org.sonar.server.computation.qualitygate.Condition;
import org.sonar.server.computation.qualitygate.ConditionEvaluator;
import org.sonar.server.computation.qualitygate.EvaluationResult;
import org.sonar.server.computation.qualitygate.EvaluationResultTextConverter;
import org.sonar.server.computation.qualitygate.QualityGate;
import org.sonar.server.computation.qualitygate.QualityGateHolder;

import static org.sonar.server.computation.component.Component.Type.PROJECT;
@@ -85,9 +86,12 @@ public class QualityGateMeasuresStep implements ComputationStep {
private void executeForProject(Component project) {
QualityGateDetailsDataBuilder builder = new QualityGateDetailsDataBuilder();

updateMeasures(project, qualityGateHolder.getQualityGate().getConditions(), builder);
Optional<QualityGate> qualityGate = qualityGateHolder.getQualityGate();
if (qualityGate.isPresent()) {
updateMeasures(project, qualityGate.get().getConditions(), builder);

addProjectMeasure(project, builder);
addProjectMeasure(project, builder);
}
}

private void updateMeasures(Component project, Set<Condition> conditions, QualityGateDetailsDataBuilder builder) {

+ 11
- 13
server/sonar-server/src/test/java/org/sonar/server/computation/qualitygate/MutableQualityGateHolderRule.java View File

@@ -19,27 +19,25 @@
*/
package org.sonar.server.computation.qualitygate;

import java.util.Objects;
import com.google.common.base.Optional;
import org.junit.rules.ExternalResource;

public class MutableQualityGateHolderRule extends ExternalResource implements MutableQualityGateHolder {
private QualityGate qualityGate;
private MutableQualityGateHolder delegate = new QualityGateHolderImpl();

@Override
public void setQualityGate(QualityGate qualityGate) {
Objects.requireNonNull(qualityGate);
if (this.qualityGate != null) {
throw new IllegalStateException("QualityGate can not be set more than once");
}
this.qualityGate = qualityGate;
delegate.setQualityGate(qualityGate);
}

@Override
public QualityGate getQualityGate() {
if (this.qualityGate == null) {
throw new IllegalStateException("QualityGate has not been set");
}
return qualityGate;
public void setNoQualityGate() {
delegate.setNoQualityGate();
}

@Override
public Optional<QualityGate> getQualityGate() {
return delegate.getQualityGate();
}

@Override
@@ -48,6 +46,6 @@ public class MutableQualityGateHolderRule extends ExternalResource implements Mu
}

public void reset() {
this.qualityGate = null;
this.delegate = new QualityGateHolderImpl();
}
}

+ 11
- 1
server/sonar-server/src/test/java/org/sonar/server/computation/qualitygate/QualityGateHolderImplTest.java View File

@@ -23,6 +23,7 @@ import java.util.Collections;
import org.junit.Test;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.guava.api.Assertions.assertThat;

public class QualityGateHolderImplTest {

@@ -52,7 +53,16 @@ public class QualityGateHolderImplTest {

holder.setQualityGate(QUALITY_GATE);

assertThat(holder.getQualityGate()).isSameAs(QUALITY_GATE);
assertThat(holder.getQualityGate().get()).isSameAs(QUALITY_GATE);
}

@Test
public void getQualityGate_returns_absent_if_holder_initialized_with_setNoQualityGate() {
QualityGateHolderImpl holder = new QualityGateHolderImpl();

holder.setNoQualityGate();

assertThat(holder.getQualityGate()).isAbsent();
}

}

+ 13
- 17
server/sonar-server/src/test/java/org/sonar/server/computation/step/QualityGateLoadingStepTest.java View File

@@ -23,6 +23,7 @@ import com.google.common.base.Optional;
import java.util.Collections;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.config.Settings;
import org.sonar.server.computation.batch.TreeRootHolderRule;
import org.sonar.server.computation.component.Component;
@@ -34,6 +35,7 @@ import org.sonar.server.computation.qualitygate.QualityGate;
import org.sonar.server.computation.qualitygate.QualityGateService;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.guava.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -41,8 +43,10 @@ import static org.mockito.Mockito.when;

public class QualityGateLoadingStepTest {
private static final String PROJECT_KEY = "project key";
public static final DumbComponent PROJECT_ALONE = DumbComponent.builder(Component.Type.PROJECT, 1).setKey(PROJECT_KEY).build();
private static final DumbComponent PROJECT_ALONE = DumbComponent.builder(Component.Type.PROJECT, 1).setKey(PROJECT_KEY).build();

@Rule
public ExpectedException expectedException = ExpectedException.none();
@Rule
public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
@Rule
@@ -60,7 +64,7 @@ public class QualityGateLoadingStepTest {

underTest.execute();

verifyDefaultQualityGateHasBeenSet();
verifyNoQualityGate();

// verify only project is processed
verify(projectSettingsRepository).getProjectSettings(PROJECT_KEY);
@@ -69,20 +73,13 @@ public class QualityGateLoadingStepTest {

@Test
public void execute_sets_default_QualityGate_when_property_value_is_not_a_long() {
verify_execute_sets_default_QualityGate_when_property_value_is_not_a_long("");
verify_execute_sets_default_QualityGate_when_property_value_is_not_a_long(" ");
verify_execute_sets_default_QualityGate_when_property_value_is_not_a_long(" 10 sds ");
}
expectedException.expect(IllegalStateException.class);
expectedException.expectMessage(String.format("Unsupported value (%s) in property sonar.qualitygate", "10 sds"));

private void verify_execute_sets_default_QualityGate_when_property_value_is_not_a_long(String value) {
treeRootHolder.setRoot(PROJECT_ALONE);
when(projectSettingsRepository.getProjectSettings(PROJECT_KEY)).thenReturn(new Settings().setProperty("sonar.qualitygate", value));
when(projectSettingsRepository.getProjectSettings(PROJECT_KEY)).thenReturn(new Settings().setProperty("sonar.qualitygate", "10 sds"));

underTest.execute();

verifyDefaultQualityGateHasBeenSet();

mutableQualityGateHolder.reset();
}

@Test
@@ -93,7 +90,7 @@ public class QualityGateLoadingStepTest {

underTest.execute();

verifyDefaultQualityGateHasBeenSet();
verifyNoQualityGate();
}

@Test
@@ -106,12 +103,11 @@ public class QualityGateLoadingStepTest {

underTest.execute();

assertThat(mutableQualityGateHolder.getQualityGate()).isSameAs(qualityGate);
assertThat(mutableQualityGateHolder.getQualityGate().get()).isSameAs(qualityGate);
}

private void verifyDefaultQualityGateHasBeenSet() {
assertThat(mutableQualityGateHolder.getQualityGate().getName()).isEqualTo("default Quality Gate");
assertThat(mutableQualityGateHolder.getQualityGate().getConditions()).isEmpty();
private void verifyNoQualityGate() {
assertThat(mutableQualityGateHolder.getQualityGate()).isAbsent();
}

}

+ 9
- 0
server/sonar-server/src/test/java/org/sonar/server/computation/step/QualityGateMeasuresStepTest.java View File

@@ -112,6 +112,15 @@ public class QualityGateMeasuresStepTest {
verifyNoMoreInteractions(measureRepository);
}

@Test
public void no_measure_if_there_is_no_qualitygate() {
qualityGateHolder.setNoQualityGate();

underTest.execute();

verifyNoMoreInteractions(measureRepository);
}

@Test
public void new_measures_are_created_even_if_there_is_no_rawMeasure_for_metric_of_condition() {
Condition equals2Condition = createEqualsCondition(INT_METRIC_1, "2", null);

Loading…
Cancel
Save