@Test public void hashcode_is_based_on_all_fields() { EvaluatedQualityGate.Builder builder = this.builder .setQualityGate(ONE_CONDITION_QUALITY_GATE) .setStatus(Level.ERROR) .addCondition(CONDITION_1, EvaluatedCondition.EvaluationStatus.ERROR, "foo"); EvaluatedQualityGate underTest = builder.build(); assertThat(underTest.hashCode()).isEqualTo(builder.build().hashCode()); assertThat(underTest.hashCode()).isNotSameAs(builder.build().hashCode()); assertThat(underTest.hashCode()).isNotEqualTo(null); assertThat(underTest.hashCode()).isNotEqualTo(new Object().hashCode()); assertThat(underTest.hashCode()).isNotEqualTo(builder.setQualityGate(new QualityGate("other_id", QUALITY_GATE_NAME, singleton(CONDITION_1))).build().hashCode()); assertThat(underTest.hashCode()).isNotEqualTo(builder.setQualityGate(ONE_CONDITION_QUALITY_GATE).setStatus(Level.OK).build().hashCode()); assertThat(underTest.hashCode()).isNotEqualTo(newBuilder() .setQualityGate(ONE_CONDITION_QUALITY_GATE) .setStatus(Level.ERROR) .addCondition(CONDITION_1, EvaluatedCondition.EvaluationStatus.OK, "foo") .build().hashCode()); } }
@Test public void verify_getters_when_no_condition() { EvaluatedQualityGate underTest = builder .setQualityGate(NO_CONDITION_QUALITY_GATE) .setStatus(randomStatus) .build(); assertThat(underTest.getQualityGate()).isEqualTo(NO_CONDITION_QUALITY_GATE); assertThat(underTest.getStatus()).isEqualTo(randomStatus); assertThat(underTest.getEvaluatedConditions()).isEmpty(); }
public EvaluatedQualityGate build() { return new EvaluatedQualityGate( this.qualityGate, this.status, checkEvaluatedConditions(qualityGate, evaluatedConditions), ignoredConditionsOnSmallChangeset); }
public static String toJson(EvaluatedQualityGate gate) { JsonObject details = new JsonObject(); details.addProperty(FIELD_LEVEL, gate.getStatus().name()); JsonArray conditionResults = new JsonArray(); for (EvaluatedCondition condition : gate.getEvaluatedConditions()) { conditionResults.add(toJson(condition)); } details.add("conditions", conditionResults); details.addProperty(FIELD_IGNORED_CONDITIONS, gate.hasIgnoredConditionsOnSmallChangeset()); return details.toString(); }
@Override public EvaluatedQualityGate evaluate(QualityGate gate, Measures measures) { checkState(this.measures == null); this.measures = measures; EvaluatedQualityGate.Builder builder = EvaluatedQualityGate.newBuilder().setQualityGate(gate).setStatus(Metric.Level.OK); for (Condition condition : gate.getConditions()) { builder.addCondition(condition, EvaluatedCondition.EvaluationStatus.OK, "bar"); } return builder.build(); }
private static boolean isQGStatusUnchanged(QGChangeEvent qualityGateEvent, Optional<EvaluatedQualityGate> evaluatedQualityGate) { Optional<Metric.Level> previousStatus = qualityGateEvent.getPreviousStatus(); if (!previousStatus.isPresent() && !evaluatedQualityGate.isPresent()) { return true; } return previousStatus .map(previousQGStatus -> evaluatedQualityGate .filter(newQualityGate -> newQualityGate.getStatus() == previousQGStatus) .isPresent()) .orElse(false); }
@Test public void refreshGateStatus_generates_gate_related_measures() { ComponentDto project = ComponentTesting.newPublicProjectDto(newOrganizationDto()); MetricDto conditionMetric = newMetricDto(); MetricDto statusMetric = newMetricDto().setKey(CoreMetrics.ALERT_STATUS_KEY); MetricDto detailsMetric = newMetricDto().setKey(CoreMetrics.QUALITY_GATE_DETAILS_KEY); Condition condition = new Condition(conditionMetric.getKey(), Condition.Operator.GREATER_THAN, "10"); QualityGate gate = new QualityGate("1", "foo", ImmutableSet.of(condition)); MeasureMatrix matrix = new MeasureMatrix(singleton(project), asList(conditionMetric, statusMetric, detailsMetric), emptyList()); EvaluatedQualityGate result = underTest.refreshGateStatus(project, gate, matrix); QualityGateEvaluator.Measures measures = qualityGateEvaluator.getCalledMeasures(); assertThat(measures.get(conditionMetric.getKey())).isEmpty(); assertThat(result.getStatus()).isEqualTo(Metric.Level.OK); assertThat(result.getEvaluatedConditions()) .extracting(EvaluatedCondition::getStatus) .containsExactly(EvaluatedCondition.EvaluationStatus.OK); assertThat(matrix.getMeasure(project, CoreMetrics.ALERT_STATUS_KEY).get().getDataAsString()).isEqualTo(Metric.Level.OK.name()); assertThat(matrix.getMeasure(project, CoreMetrics.QUALITY_GATE_DETAILS_KEY).get().getDataAsString()) .isNotEmpty() // json format .startsWith("{").endsWith("}"); }
public static String toJson(EvaluatedQualityGate gate) { JsonObject details = new JsonObject(); details.addProperty(FIELD_LEVEL, gate.getStatus().name()); JsonArray conditionResults = new JsonArray(); for (EvaluatedCondition condition : gate.getEvaluatedConditions()) { conditionResults.add(toJson(condition)); } details.add("conditions", conditionResults); details.addProperty(FIELD_IGNORED_CONDITIONS, gate.hasIgnoredConditionsOnSmallChangeset()); return details.toString(); }
@Override public EvaluatedQualityGate evaluate(QualityGate gate, Measures measures) { EvaluatedQualityGate.Builder result = EvaluatedQualityGate.newBuilder() .setQualityGate(gate); boolean isSmallChangeset = isSmallChangeset(measures); gate.getConditions().forEach(condition -> { String metricKey = condition.getMetricKey(); EvaluatedCondition evaluation = ConditionEvaluator.evaluate(condition, measures); if (isSmallChangeset && evaluation.getStatus() != EvaluationStatus.OK && METRICS_TO_IGNORE_ON_SMALL_CHANGESETS.contains(metricKey)) { result.addCondition(new EvaluatedCondition(evaluation.getCondition(), EvaluationStatus.OK, evaluation.getValue().orElse(null))); result.setIgnoredConditionsOnSmallChangeset(true); } else { result.addCondition(evaluation); } }); result.setStatus(overallStatusOf(result.getEvaluatedConditions())); return result.build(); }
@Test public void evaluate_is_OK_for_empty_qgate() { QualityGate gate = mock(QualityGate.class); QualityGateEvaluator.Measures measures = mock(QualityGateEvaluator.Measures.class); EvaluatedQualityGate evaluatedQualityGate = underTest.evaluate(gate, measures); assertThat(evaluatedQualityGate.getStatus()).isEqualTo(Metric.Level.OK); } }
@Test public void verify_getters() { EvaluatedQualityGate underTest = builder .setQualityGate(ONE_CONDITION_QUALITY_GATE) .setStatus(randomStatus) .addCondition(CONDITION_1, randomEvaluationStatus, randomValue) .build(); assertThat(underTest.getQualityGate()).isEqualTo(ONE_CONDITION_QUALITY_GATE); assertThat(underTest.getStatus()).isEqualTo(randomStatus); assertThat(underTest.getEvaluatedConditions()) .containsOnly(new EvaluatedCondition(CONDITION_1, randomEvaluationStatus, randomValue)); }
private static org.sonar.server.webhook.ProjectAnalysis convert(ProjectAnalysis projectAnalysis) { CeTask ceTask = new CeTask(projectAnalysis.getCeTask().getId(), CeTask.Status.valueOf(projectAnalysis.getCeTask().getStatus().name())); Analysis analysis = projectAnalysis.getAnalysis().map(a -> new Analysis(a.getAnalysisUuid(), a.getDate().getTime())).orElse(null); Branch branch = projectAnalysis.getBranch().map(b -> new Branch(b.isMain(), b.getName().orElse(null), Branch.Type.valueOf(b.getType().name()))).orElse(null); EvaluatedQualityGate qualityGate = Optional.ofNullable(projectAnalysis.getQualityGate()) .map(qg -> { EvaluatedQualityGate.Builder builder = EvaluatedQualityGate.newBuilder(); Set<Condition> conditions = qg.getConditions().stream() .map(q -> { Condition condition = new Condition(q.getMetricKey(), Condition.Operator.valueOf(q.getOperator().name()), q.getErrorThreshold()); builder.addCondition(condition, EvaluatedCondition.EvaluationStatus.valueOf(q.getStatus().name()), q.getStatus() == org.sonar.api.ce.posttask.QualityGate.EvaluationStatus.NO_VALUE ? null : q.getValue()); return condition; }) .collect(MoreCollectors.toSet()); return builder.setQualityGate(new org.sonar.server.qualitygate.QualityGate(qg.getId(), qg.getName(), conditions)) .setStatus(Metric.Level.valueOf(qg.getStatus().name())) .build(); }) .orElse(null); Long date = projectAnalysis.getAnalysis().map(a -> a.getDate().getTime()).orElse(null); Map<String, String> properties = projectAnalysis.getScannerContext().getProperties(); Project project = new Project(projectAnalysis.getProject().getUuid(), projectAnalysis.getProject().getKey(), projectAnalysis.getProject().getName()); return new org.sonar.server.webhook.ProjectAnalysis(project, ceTask, analysis, branch, qualityGate, date, properties); } }
@Override public EvaluatedQualityGate refreshGateStatus(ComponentDto project, QualityGate gate, MeasureMatrix measureMatrix) { QualityGateEvaluator.Measures measures = metricKey -> { Optional<LiveMeasureDto> liveMeasureDto = measureMatrix.getMeasure(project, metricKey); if (!liveMeasureDto.isPresent()) { return Optional.empty(); } MetricDto metric = measureMatrix.getMetric(liveMeasureDto.get().getMetricId()); return Optional.of(new LiveMeasure(liveMeasureDto.get(), metric)); }; EvaluatedQualityGate evaluatedGate = evaluator.evaluate(gate, measures); measureMatrix.setValue(project, CoreMetrics.ALERT_STATUS_KEY, evaluatedGate.getStatus().name()); measureMatrix.setValue(project, CoreMetrics.QUALITY_GATE_DETAILS_KEY, QualityGateConverter.toJson(evaluatedGate)); return evaluatedGate; }
public EvaluatedQualityGate build() { return new EvaluatedQualityGate( this.qualityGate, this.status, checkEvaluatedConditions(qualityGate, evaluatedConditions), ignoredConditionsOnSmallChangeset); }
@Test public void verify_getters_when_multiple_conditions() { QualityGate qualityGate = new QualityGate(QUALITY_GATE_ID, QUALITY_GATE_NAME, ImmutableSet.of(CONDITION_1, CONDITION_2)); EvaluatedQualityGate underTest = builder .setQualityGate(qualityGate) .setStatus(randomStatus) .addCondition(CONDITION_1, randomEvaluationStatus, randomValue) .addCondition(CONDITION_2, EvaluatedCondition.EvaluationStatus.ERROR, "bad") .build(); assertThat(underTest.getQualityGate()).isEqualTo(qualityGate); assertThat(underTest.getStatus()).isEqualTo(randomStatus); assertThat(underTest.getEvaluatedConditions()).containsOnly( new EvaluatedCondition(CONDITION_1, randomEvaluationStatus, randomValue), new EvaluatedCondition(CONDITION_2, EvaluatedCondition.EvaluationStatus.ERROR, "bad")); }
@Test public void equals_is_based_on_all_fields() { EvaluatedQualityGate.Builder builder = this.builder .setQualityGate(ONE_CONDITION_QUALITY_GATE) .setStatus(Level.ERROR) .addCondition(CONDITION_1, EvaluatedCondition.EvaluationStatus.ERROR, "foo"); EvaluatedQualityGate underTest = builder.build(); assertThat(underTest).isEqualTo(builder.build()); assertThat(underTest).isNotSameAs(builder.build()); assertThat(underTest).isNotEqualTo(null); assertThat(underTest).isNotEqualTo(new Object()); assertThat(underTest).isNotEqualTo(builder.setQualityGate(new QualityGate("other_id", QUALITY_GATE_NAME, singleton(CONDITION_1))).build()); assertThat(underTest).isNotEqualTo(builder.setQualityGate(ONE_CONDITION_QUALITY_GATE).setStatus(Level.OK).build()); assertThat(underTest).isNotEqualTo(newBuilder() .setQualityGate(ONE_CONDITION_QUALITY_GATE) .setStatus(Level.ERROR) .addCondition(CONDITION_1, EvaluatedCondition.EvaluationStatus.OK, "foo") .build()); }
private static QGChangeEvent newQGChangeEvent(ComponentAndBranch branch, SnapshotDto analysis, Configuration configuration, @Nullable EvaluatedQualityGate evaluatedQualityGate) { Metric.Level previousStatus = randomLevel(); if (evaluatedQualityGate != null) { Metric.Level otherLevel = stream(Metric.Level.values()) .filter(s -> s != previousStatus) .toArray(Metric.Level[]::new)[new Random().nextInt(Metric.Level.values().length - 1)]; when(evaluatedQualityGate.getStatus()).thenReturn(otherLevel); } return new QGChangeEvent(branch.component, branch.branch, analysis, configuration, previousStatus, () -> Optional.ofNullable(evaluatedQualityGate)); }
private static void writeQualityGate(JsonWriter writer, EvaluatedQualityGate gate) { writer .name("qualityGate") .beginObject() .prop("name", gate.getQualityGate().getName()) .prop(PROPERTY_STATUS, gate.getStatus().toString()) .name("conditions") .beginArray(); for (EvaluatedCondition evaluatedCondition : gate.getEvaluatedConditions()) { Condition condition = evaluatedCondition.getCondition(); writer .beginObject() .prop("metric", condition.getMetricKey()) .prop("operator", condition.getOperator().name()); evaluatedCondition.getValue().ifPresent(t -> writer.prop("value", t)); writer .prop(PROPERTY_STATUS, evaluatedCondition.getStatus().name()) .prop("errorThreshold", condition.getErrorThreshold()) .endObject(); } writer .endArray() .endObject(); }
Condition.Operator.valueOf(condition.getOperator().name()), condition.getErrorThreshold()); webQualityGate = EvaluatedQualityGate.newBuilder() .setQualityGate(new org.sonar.server.qualitygate.QualityGate(qualityGate.getId(), qualityGate.getName(), Collections.singleton(qgCondition))) .setStatus(Metric.Level.valueOf(qualityGate.getStatus().name()))
@Test public void onIssueChanges_has_no_effect_if_event_has_same_status_in_previous_and_new_QG() { Configuration configuration = mock(Configuration.class); Metric.Level previousStatus = randomLevel(); when(newQualityGate.getStatus()).thenReturn(previousStatus); QGChangeEvent qualityGateEvent = newQGChangeEvent(configuration, previousStatus, newQualityGate); mockWebhookEnabled(qualityGateEvent.getProject()); underTest.onIssueChanges(qualityGateEvent, CHANGED_ISSUES_ARE_IGNORED); verifyZeroInteractions(webhookPayloadFactory, mockedDbClient); }