private List<QualityGateConditionDto> createBuiltInConditions(QualityGateDto qg) { List<QualityGateConditionDto> conditions = new ArrayList<>(); conditions.add(qualityGateConditionsUpdater.createCondition(dbSession, qg, NEW_SECURITY_RATING_KEY, OPERATOR_GREATER_THAN, "1")); conditions.add(qualityGateConditionsUpdater.createCondition(dbSession, qg, NEW_RELIABILITY_RATING_KEY, OPERATOR_GREATER_THAN, "1")); conditions.add(qualityGateConditionsUpdater.createCondition(dbSession, qg, NEW_MAINTAINABILITY_RATING_KEY, OPERATOR_GREATER_THAN, "1")); conditions.add(qualityGateConditionsUpdater.createCondition(dbSession, qg, NEW_COVERAGE_KEY, OPERATOR_LESS_THAN, "80")); conditions.add(qualityGateConditionsUpdater.createCondition(dbSession, qg, NEW_DUPLICATED_LINES_DENSITY_KEY, OPERATOR_GREATER_THAN, "3")); return conditions; } }
private void updateQualityConditionsIfRequired(DbSession dbSession, QualityGateDto builtin) { Map<Long, String> idToKeyMetric = dbClient.metricDao().selectAll(dbSession).stream() .collect(toMap(metricDto -> metricDto.getId().longValue(), MetricDto::getKey)); List<QualityGateCondition> qualityGateConditions = qualityGateConditionDao.selectForQualityGate(dbSession, builtin.getId()) .stream() .map(dto -> QualityGateCondition.from(dto, idToKeyMetric)) .collect(MoreCollectors.toList()); // Find all conditions that are not present in QUALITY_GATE_CONDITIONS // Those conditions must be deleted List<QualityGateCondition> qgConditionsToBeDeleted = new ArrayList<>(qualityGateConditions); qgConditionsToBeDeleted.removeAll(QUALITY_GATE_CONDITIONS); qgConditionsToBeDeleted .forEach(qgc -> qualityGateConditionDao.delete(qgc.toQualityGateDto(builtin.getId()), dbSession)); // Find all conditions that are not present in qualityGateConditions // Those conditions must be created List<QualityGateCondition> qgConditionsToBeCreated = new ArrayList<>(QUALITY_GATE_CONDITIONS); qgConditionsToBeCreated.removeAll(qualityGateConditions); qgConditionsToBeCreated .forEach(qgc -> qualityGateConditionsUpdater.createCondition(dbSession, builtin, qgc.getMetricKey(), qgc.getOperator(), qgc.getErrorThreshold())); if (!qgConditionsToBeCreated.isEmpty() || !qgConditionsToBeDeleted.isEmpty()) { LOGGER.info("Built-in quality gate's conditions of [{}] has been updated", BUILTIN_QUALITY_GATE_NAME); } }
@Test public void upgrade_should_remove_deleted_condition() { insertMetrics(); QualityGateDto builtInQualityGate = db.qualityGates().insertBuiltInQualityGate(); createBuiltInConditions(builtInQualityGate); // Add another condition qualityGateConditionsUpdater.createCondition(dbSession, builtInQualityGate, NEW_SECURITY_REMEDIATION_EFFORT_KEY, OPERATOR_GREATER_THAN, "5"); dbSession.commit(); underTest.start(); assertThat(db.countRowsOfTable("quality_gates")).isEqualTo(1); verifyCorrectBuiltInQualityGate(); assertThat( logTester.logs(LoggerLevel.INFO).contains("Built-in quality gate's conditions of [Sonar way] has been updated")).isTrue(); }
@Test public void fail_to_create_condition_on_missing_metric() { QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); expectedException.expect(NotFoundException.class); expectedException.expectMessage("There is no metric with key=new_coverage"); underTest.createCondition(db.getSession(), qualityGate, "new_coverage", "LT", "80"); }
@Test public void create_condition_on_rating_metric() { MetricDto metric = insertMetric(RATING, SQALE_RATING_KEY); QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); QualityGateConditionDto result = underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "GT", "3"); verifyCondition(result, qualityGate, metric, "GT", "3"); }
@Test public void fail_to_create_condition_on_greater_than_E() { MetricDto metric = insertMetric(RATING, SQALE_RATING_KEY); QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); expectedException.expect(BadRequestException.class); expectedException.expectMessage("There's no worse rating than E (5)"); underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "GT", "5"); }
@Test public void create_error_condition() { MetricDto metric = insertMetric(INT, "new_coverage"); QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); QualityGateConditionDto result = underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "LT", "80"); verifyCondition(result, qualityGate, metric, "LT", "80"); }
@Test public void fail_to_create_condition_when_condition_on_same_metric_already_exist() { MetricDto metric = insertMetric(PERCENT); QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); db.qualityGates().addCondition(qualityGate, metric); expectedException.expect(BadRequestException.class); expectedException.expectMessage(format("Condition on metric '%s' already exists.", metric.getShortName())); underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "LT", "80"); }
@Test public void create_condition_throws_NPE_if_errorThreshold_is_null() { MetricDto metric = insertMetric(RATING, SQALE_RATING_KEY); QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); expectedException.expect(NullPointerException.class); expectedException.expectMessage("errorThreshold can not be null"); underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "GT", null); }
@Test public void fail_to_create_error_condition_on_invalid_rating_metric() { MetricDto metric = insertMetric(RATING, SQALE_RATING_KEY); QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); expectedException.expect(BadRequestException.class); expectedException.expectMessage("'80' is not a valid rating"); underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "GT", "80"); }
@Test @UseDataProvider("invalid_operators_and_direction") public void fail_to_create_condition_on_not_allowed_operator_for_metric_direction(String operator, int direction) { MetricDto metric = db.measures().insertMetric(m -> m.setKey("key").setValueType(INT.name()).setHidden(false).setDirection(direction)); QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); expectedException.expect(BadRequestException.class); expectedException.expectMessage(format("Operator %s is not allowed for this metric.", operator)); underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), operator, "90"); }
@Test @UseDataProvider("invalid_values") public void fail_to_create_error_INT_condition_when_value_is_not_an_integer(Metric.ValueType valueType, String value) { MetricDto metric = db.measures().insertMetric(m -> m.setValueType(valueType.name()).setHidden(false).setDirection(0)); QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); expectedException.expect(BadRequestException.class); expectedException.expectMessage(format("Invalid value '%s' for metric '%s'", value, metric.getShortName())); underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "LT", value); }
@Test @UseDataProvider("invalid_metrics") public void fail_to_create_condition_on_invalid_metric(String metricKey, Metric.ValueType valueType, boolean hidden) { MetricDto metric = db.measures().insertMetric(m -> m.setKey(metricKey).setValueType(valueType.name()).setHidden(hidden).setDirection(0)); QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); expectedException.expect(BadRequestException.class); expectedException.expectMessage(format("Metric '%s' cannot be used to define a condition", metric.getKey())); underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "LT", "80"); }
@Override public void handle(Request request, Response response) { int gateId = request.mandatoryParamAsInt(PARAM_GATE_ID); String metric = request.mandatoryParam(PARAM_METRIC); String operator = request.mandatoryParam(PARAM_OPERATOR); String error = request.mandatoryParam(PARAM_ERROR); try (DbSession dbSession = dbClient.openSession(false)) { OrganizationDto organization = wsSupport.getOrganization(dbSession, request); QGateWithOrgDto qualityGate = wsSupport.getByOrganizationAndId(dbSession, organization, gateId); wsSupport.checkCanEdit(qualityGate); QualityGateConditionDto condition = qualityGateConditionsUpdater.createCondition(dbSession, qualityGate, metric, operator, error); CreateConditionResponse.Builder createConditionResponse = CreateConditionResponse.newBuilder() .setId(condition.getId()) .setMetric(condition.getMetricKey()) .setError(condition.getErrorThreshold()) .setOp(condition.getOperator()); writeProtobuf(createConditionResponse.build(), request, response); dbSession.commit(); } }
@Test @UseDataProvider("valid_values") public void create_error_condition(Metric.ValueType valueType, String value) { MetricDto metric = db.measures().insertMetric(m -> m.setValueType(valueType.name()).setHidden(false).setDirection(0)); QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); QualityGateConditionDto result = underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), "LT", value); verifyCondition(result, qualityGate, metric, "LT", value); }
@Test @UseDataProvider("valid_operators_and_direction") public void create_condition_with_valid_operators_and_direction(String operator, int direction) { MetricDto metric = db.measures().insertMetric(m -> m.setKey("key").setValueType(INT.name()).setHidden(false).setDirection(direction)); QualityGateDto qualityGate = db.qualityGates().insertQualityGate(db.getDefaultOrganization()); QualityGateConditionDto result = underTest.createCondition(db.getSession(), qualityGate, metric.getKey(), operator, "80"); verifyCondition(result, qualityGate, metric, operator, "80"); }
private void updateQualityConditionsIfRequired(DbSession dbSession, QualityGateDto builtin) { Map<Long, String> idToKeyMetric = dbClient.metricDao().selectAll(dbSession).stream() .collect(toMap(metricDto -> metricDto.getId().longValue(), MetricDto::getKey)); List<QualityGateCondition> qualityGateConditions = qualityGateConditionDao.selectForQualityGate(dbSession, builtin.getId()) .stream() .map(dto -> QualityGateCondition.from(dto, idToKeyMetric)) .collect(MoreCollectors.toList()); // Find all conditions that are not present in QUALITY_GATE_CONDITIONS // Those conditions must be deleted List<QualityGateCondition> qgConditionsToBeDeleted = new ArrayList<>(qualityGateConditions); qgConditionsToBeDeleted.removeAll(QUALITY_GATE_CONDITIONS); qgConditionsToBeDeleted.stream() .forEach(qgc -> qualityGateConditionDao.delete(qgc.toQualityGateDto(builtin.getId()), dbSession)); // Find all conditions that are not present in qualityGateConditions // Those conditions must be created List<QualityGateCondition> qgConditionsToBeCreated = new ArrayList<>(QUALITY_GATE_CONDITIONS); qgConditionsToBeCreated.removeAll(qualityGateConditions); qgConditionsToBeCreated.stream() .forEach(qgc -> qualityGateConditionsUpdater.createCondition(dbSession, builtin, qgc.getMetricKey(), qgc.getOperator(), qgc.getWarningThreshold(), qgc.getErrorThreshold(), qgc.getPeriod())); if (!qgConditionsToBeCreated.isEmpty() || !qgConditionsToBeDeleted.isEmpty()) { LOGGER.info("Built-in quality gate's conditions of [{}] has been updated", BUILTIN_QUALITY_GATE_NAME); } }
@Override public void handle(Request request, Response response) { int gateId = request.mandatoryParamAsInt(PARAM_GATE_ID); String metric = request.mandatoryParam(PARAM_METRIC); String operator = request.mandatoryParam(PARAM_OPERATOR); String warning = request.param(PARAM_WARNING); String error = request.param(PARAM_ERROR); Integer period = request.paramAsInt(PARAM_PERIOD); try (DbSession dbSession = dbClient.openSession(false)) { OrganizationDto organization = wsSupport.getOrganization(dbSession, request); QGateWithOrgDto qualityGate = qualityGateFinder.getByOrganizationAndId(dbSession, organization, gateId); wsSupport.checkCanEdit(qualityGate); QualityGateConditionDto condition = qualityGateConditionsUpdater.createCondition(dbSession, qualityGate, metric, operator, emptyToNull(warning), emptyToNull(error), period); CreateConditionResponse.Builder createConditionResponse = CreateConditionResponse.newBuilder() .setId(condition.getId()) .setMetric(condition.getMetricKey()) .setOp(condition.getOperator()); setNullable(condition.getWarningThreshold(), createConditionResponse::setWarning); setNullable(condition.getErrorThreshold(), createConditionResponse::setError); setNullable(condition.getPeriod(), createConditionResponse::setPeriod); writeProtobuf(createConditionResponse.build(), request, response); dbSession.commit(); } }