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); }
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(); }
@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); } }
@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; }
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)); }
@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); }
@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(); }
@Test @UseDataProvider("allCombinationsOfStatuses") public void onIssueChanges_has_no_effect_if_no_webhook_is_configured(Metric.Level previousStatus, Metric.Level newStatus) { Configuration configuration1 = mock(Configuration.class); when(newQualityGate.getStatus()).thenReturn(newStatus); QGChangeEvent qualityGateEvent = newQGChangeEvent(configuration1, previousStatus, newQualityGate); mockWebhookDisabled(qualityGateEvent.getProject()); mockedUnderTest.onIssueChanges(qualityGateEvent, CHANGED_ISSUES_ARE_IGNORED); verify(webHooks).isEnabled(qualityGateEvent.getProject()); verifyZeroInteractions(webhookPayloadFactory, mockedDbClient); }
@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)); }
@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 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("}"); }
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(); }
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); }
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 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; }
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("onLeakPeriod", condition.isOnLeakPeriod()) .prop("errorThreshold", condition.getErrorThreshold().orElse(null)) .prop("warningThreshold", condition.getWarningThreshold().orElse(null)) .endObject(); } writer .endArray() .endObject(); }