diff options
author | Sébastien Lesaint <sebastien.lesaint@sonarsource.com> | 2018-07-03 12:26:32 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2018-07-09 10:39:33 +0200 |
commit | 9e3bc71eb9e0ac3b384c2fbfaa8355596e5ea7f2 (patch) | |
tree | 5aa1306fd44789b6d17b3274c353420f492727d5 /server/sonar-server-common/src | |
parent | 12349c8c275dc316e09451c4f468376e26be53b3 (diff) | |
download | sonarqube-9e3bc71eb9e0ac3b384c2fbfaa8355596e5ea7f2.tar.gz sonarqube-9e3bc71eb9e0ac3b384c2fbfaa8355596e5ea7f2.zip |
sonar-ce-task-projectanalysis depends on only sonar-server-common
Diffstat (limited to 'server/sonar-server-common/src')
12 files changed, 957 insertions, 0 deletions
diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/measure/DebtRatingGrid.java b/server/sonar-server-common/src/main/java/org/sonar/server/measure/DebtRatingGrid.java new file mode 100644 index 00000000000..faac02fc016 --- /dev/null +++ b/server/sonar-server-common/src/main/java/org/sonar/server/measure/DebtRatingGrid.java @@ -0,0 +1,110 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.measure; + +import com.google.common.annotations.VisibleForTesting; +import java.util.Arrays; +import java.util.EnumMap; +import java.util.Map; +import org.sonar.api.config.Configuration; + +import static com.google.common.base.Preconditions.checkState; +import static java.lang.String.format; +import static org.sonar.api.CoreProperties.RATING_GRID; +import static org.sonar.api.CoreProperties.RATING_GRID_DEF_VALUES; +import static org.sonar.server.measure.Rating.A; +import static org.sonar.server.measure.Rating.B; +import static org.sonar.server.measure.Rating.C; +import static org.sonar.server.measure.Rating.D; +import static org.sonar.server.measure.Rating.E; + +public class DebtRatingGrid { + + private final double[] gridValues; + private final EnumMap<Rating, Bounds> ratingBounds; + + public DebtRatingGrid(Configuration config) { + try { + String[] grades = config.getStringArray(RATING_GRID); + gridValues = new double[4]; + for (int i = 0; i < 4; i++) { + gridValues[i] = Double.parseDouble(grades[i]); + } + this.ratingBounds = buildRatingBounds(gridValues); + } catch (Exception e) { + throw new IllegalArgumentException("The rating grid is incorrect. Expected something similar to '" + + RATING_GRID_DEF_VALUES + "' and got '" + config.get(RATING_GRID).orElse("") + "'", e); + } + } + + public DebtRatingGrid(double[] gridValues) { + this.gridValues = Arrays.copyOf(gridValues, gridValues.length); + this.ratingBounds = buildRatingBounds(gridValues); + } + + private static EnumMap<Rating, Bounds> buildRatingBounds(double[] gridValues) { + checkState(gridValues.length == 4, "Rating grid should contains 4 values"); + EnumMap<Rating, Bounds> ratingBounds = new EnumMap<>(Rating.class); + ratingBounds.put(A, new Bounds(0d, gridValues[0])); + ratingBounds.put(B, new Bounds(gridValues[0], gridValues[1])); + ratingBounds.put(C, new Bounds(gridValues[1], gridValues[2])); + ratingBounds.put(D, new Bounds(gridValues[2], gridValues[3])); + ratingBounds.put(E, new Bounds(gridValues[3], Double.MAX_VALUE)); + return ratingBounds; + } + + public Rating getRatingForDensity(double value) { + return ratingBounds.entrySet().stream() + .filter(e -> e.getValue().match(value)) + .map(Map.Entry::getKey) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException(format("Invalid value '%s'", value))); + } + + public double getGradeLowerBound(Rating rating) { + if (rating.getIndex() > 1) { + return gridValues[rating.getIndex() - 2]; + } + return 0; + } + + @VisibleForTesting + public double[] getGridValues() { + return gridValues; + } + + private static class Bounds { + private final double lowerBound; + private final double higherBound; + private final boolean isLowerBoundInclusive; + + private Bounds(double lowerBound, double higherBound) { + this.lowerBound = lowerBound; + this.higherBound = higherBound; + this.isLowerBoundInclusive = lowerBound == 0; + } + + boolean match(double value) { + boolean lowerBoundMatch = isLowerBoundInclusive ? (value >= lowerBound) : (value > lowerBound); + return lowerBoundMatch && value <= higherBound; + } + } + +} diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/measure/Rating.java b/server/sonar-server-common/src/main/java/org/sonar/server/measure/Rating.java new file mode 100644 index 00000000000..873f682f998 --- /dev/null +++ b/server/sonar-server-common/src/main/java/org/sonar/server/measure/Rating.java @@ -0,0 +1,63 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.measure; + +import com.google.common.collect.ImmutableMap; +import java.util.Map; + +import static java.lang.String.format; +import static java.util.Arrays.stream; +import static org.sonar.api.rule.Severity.BLOCKER; +import static org.sonar.api.rule.Severity.CRITICAL; +import static org.sonar.api.rule.Severity.INFO; +import static org.sonar.api.rule.Severity.MAJOR; +import static org.sonar.api.rule.Severity.MINOR; + +public enum Rating { + E(5), + D(4), + C(3), + B(2), + A(1); + + private final int index; + + Rating(int index) { + this.index = index; + } + + public int getIndex() { + return index; + } + + public static Rating valueOf(int index) { + return stream(Rating.values()) + .filter(r -> r.getIndex() == index) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException(format("Unknown value '%s'", index))); + } + + public static final Map<String, Rating> RATING_BY_SEVERITY = ImmutableMap.of( + BLOCKER, E, + CRITICAL, D, + MAJOR, C, + MINOR, B, + INFO, A); +} diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/qualitygate/ShortLivingBranchQualityGate.java b/server/sonar-server-common/src/main/java/org/sonar/server/qualitygate/ShortLivingBranchQualityGate.java new file mode 100644 index 00000000000..f77b6e65ee8 --- /dev/null +++ b/server/sonar-server-common/src/main/java/org/sonar/server/qualitygate/ShortLivingBranchQualityGate.java @@ -0,0 +1,82 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.qualitygate; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import java.util.List; +import javax.annotation.CheckForNull; +import org.sonar.api.measures.CoreMetrics; + +import static org.sonar.db.qualitygate.QualityGateConditionDto.OPERATOR_GREATER_THAN; + +/** + * Offers constants describing the Hardcoded Quality Gate for short living branches and pull requests. + */ +public final class ShortLivingBranchQualityGate { + public static final long ID = -1_963_456_987L; + public static final String NAME = "Hardcoded short living branch quality gate"; + public static final List<Condition> CONDITIONS = ImmutableList.of( + new Condition(CoreMetrics.OPEN_ISSUES_KEY, OPERATOR_GREATER_THAN, "0", false), + new Condition(CoreMetrics.REOPENED_ISSUES_KEY, OPERATOR_GREATER_THAN, "0", false)); + + public static final QualityGate GATE = new QualityGate(String.valueOf(ID), NAME, ImmutableSet.of( + new org.sonar.server.qualitygate.Condition(CoreMetrics.OPEN_ISSUES_KEY, org.sonar.server.qualitygate.Condition.Operator.GREATER_THAN, "0", null, false), + new org.sonar.server.qualitygate.Condition(CoreMetrics.REOPENED_ISSUES_KEY, org.sonar.server.qualitygate.Condition.Operator.GREATER_THAN, "0", null, false))); + + private ShortLivingBranchQualityGate() { + // prevents instantiation + } + + public static final class Condition { + private final String metricKey; + private final String operator; + private final String errorThreshold; + private final boolean onLeak; + + public Condition(String metricKey, String operator, String errorThreshold, boolean onLeak) { + this.metricKey = metricKey; + this.operator = operator; + this.errorThreshold = errorThreshold; + this.onLeak = onLeak; + } + + public String getMetricKey() { + return metricKey; + } + + public String getOperator() { + return operator; + } + + public String getErrorThreshold() { + return errorThreshold; + } + + @CheckForNull + public String getWarnThreshold() { + return null; + } + + public boolean isOnLeak() { + return onLeak; + } + } +} diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/qualityprofile/QPMeasureData.java b/server/sonar-server-common/src/main/java/org/sonar/server/qualityprofile/QPMeasureData.java new file mode 100644 index 00000000000..8c4a40a68b3 --- /dev/null +++ b/server/sonar-server-common/src/main/java/org/sonar/server/qualityprofile/QPMeasureData.java @@ -0,0 +1,101 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.qualityprofile; + +import com.google.common.collect.ImmutableSortedSet; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import java.io.StringWriter; +import java.util.Comparator; +import java.util.Map; +import java.util.SortedSet; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; +import javax.annotation.concurrent.Immutable; +import org.sonar.api.utils.text.JsonWriter; +import org.sonar.core.util.UtcDateUtils; + +import static java.util.function.Function.identity; +import static org.sonar.core.util.stream.MoreCollectors.uniqueIndex; + +/** + * Represents the array of JSON objects stored in the value of the + * {@link org.sonar.api.measures.CoreMetrics#QUALITY_PROFILES} measures. + */ +@Immutable +public class QPMeasureData { + + private final SortedSet<QualityProfile> profiles; + + public QPMeasureData(Iterable<QualityProfile> qualityProfiles) { + this.profiles = ImmutableSortedSet.copyOf(QualityProfileComparator.INSTANCE, qualityProfiles); + } + + public static QPMeasureData fromJson(String json) { + return new QPMeasureData(StreamSupport.stream(new JsonParser().parse(json).getAsJsonArray().spliterator(), false) + .map(jsonElement -> { + JsonObject jsonProfile = jsonElement.getAsJsonObject(); + return new QualityProfile( + jsonProfile.get("key").getAsString(), + jsonProfile.get("name").getAsString(), + jsonProfile.get("language").getAsString(), + UtcDateUtils.parseDateTime(jsonProfile.get("rulesUpdatedAt").getAsString())); + }).collect(Collectors.toList())); + } + + public static String toJson(QPMeasureData data) { + StringWriter json = new StringWriter(); + try (JsonWriter writer = JsonWriter.of(json)) { + writer.beginArray(); + for (QualityProfile profile : data.getProfiles()) { + writer + .beginObject() + .prop("key", profile.getQpKey()) + .prop("language", profile.getLanguageKey()) + .prop("name", profile.getQpName()) + .prop("rulesUpdatedAt", UtcDateUtils.formatDateTime(profile.getRulesUpdatedAt())) + .endObject(); + } + writer.endArray(); + } + return json.toString(); + } + + public SortedSet<QualityProfile> getProfiles() { + return profiles; + } + + public Map<String, QualityProfile> getProfilesByKey() { + return profiles.stream().collect(uniqueIndex(QualityProfile::getQpKey, identity())); + } + + private enum QualityProfileComparator implements Comparator<QualityProfile> { + INSTANCE; + + @Override + public int compare(QualityProfile o1, QualityProfile o2) { + int c = o1.getLanguageKey().compareTo(o2.getLanguageKey()); + if (c == 0) { + c = o1.getQpName().compareTo(o2.getQpName()); + } + return c; + } + } +} diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/qualityprofile/QualityProfile.java b/server/sonar-server-common/src/main/java/org/sonar/server/qualityprofile/QualityProfile.java new file mode 100644 index 00000000000..024319ad7f5 --- /dev/null +++ b/server/sonar-server-common/src/main/java/org/sonar/server/qualityprofile/QualityProfile.java @@ -0,0 +1,90 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.qualityprofile; + +import com.google.common.base.MoreObjects; +import java.util.Date; +import javax.annotation.Nullable; +import javax.annotation.concurrent.Immutable; + +import static java.util.Objects.requireNonNull; + +/** + * Represents the JSON object an array of which is stored in the value of the + * {@link org.sonar.api.measures.CoreMetrics#QUALITY_PROFILES} measures. + */ +@Immutable +public class QualityProfile { + private final String qpKey; + private final String qpName; + private final String languageKey; + private final Date rulesUpdatedAt; + + public QualityProfile(String qpKey, String qpName, String languageKey, Date rulesUpdatedAt) { + this.qpKey = requireNonNull(qpKey); + this.qpName = requireNonNull(qpName); + this.languageKey = requireNonNull(languageKey); + this.rulesUpdatedAt = requireNonNull(rulesUpdatedAt); + } + + public String getQpKey() { + return qpKey; + } + + public String getQpName() { + return qpName; + } + + public String getLanguageKey() { + return languageKey; + } + + public Date getRulesUpdatedAt() { + return new Date(rulesUpdatedAt.getTime()); + } + + @Override + public boolean equals(@Nullable Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + QualityProfile qProfile = (QualityProfile) o; + return qpKey.equals(qProfile.qpKey); + } + + @Override + public int hashCode() { + return qpKey.hashCode(); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("key", qpKey) + .add("name", qpName) + .add("language", languageKey) + .add("rulesUpdatedAt", rulesUpdatedAt.getTime()) + .toString(); + } +} diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/rule/CommonRuleKeys.java b/server/sonar-server-common/src/main/java/org/sonar/server/rule/CommonRuleKeys.java new file mode 100644 index 00000000000..2c3a7aa2bc0 --- /dev/null +++ b/server/sonar-server-common/src/main/java/org/sonar/server/rule/CommonRuleKeys.java @@ -0,0 +1,46 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.rule; + +public class CommonRuleKeys { + + public static final String REPOSITORY_PREFIX = "common-"; + + public static final String INSUFFICIENT_BRANCH_COVERAGE = "InsufficientBranchCoverage"; + public static final String INSUFFICIENT_BRANCH_COVERAGE_PROPERTY = "minimumBranchCoverageRatio"; + + public static final String INSUFFICIENT_LINE_COVERAGE = "InsufficientLineCoverage"; + public static final String INSUFFICIENT_LINE_COVERAGE_PROPERTY = "minimumLineCoverageRatio"; + + public static final String INSUFFICIENT_COMMENT_DENSITY = "InsufficientCommentDensity"; + public static final String INSUFFICIENT_COMMENT_DENSITY_PROPERTY = "minimumCommentDensity"; + + public static final String DUPLICATED_BLOCKS = "DuplicatedBlocks"; + public static final String FAILED_UNIT_TESTS = "FailedUnitTests"; + public static final String SKIPPED_UNIT_TESTS = "SkippedUnitTests"; + + private CommonRuleKeys() { + // only static methods + } + + public static String commonRepositoryForLang(String language) { + return REPOSITORY_PREFIX + language; + } +} diff --git a/server/sonar-server-common/src/main/java/org/sonar/server/setting/ChildSettings.java b/server/sonar-server-common/src/main/java/org/sonar/server/setting/ChildSettings.java new file mode 100644 index 00000000000..4961afd3df1 --- /dev/null +++ b/server/sonar-server-common/src/main/java/org/sonar/server/setting/ChildSettings.java @@ -0,0 +1,83 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.setting; + +import com.google.common.collect.ImmutableMap; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import org.sonar.api.config.Configuration; +import org.sonar.api.config.Settings; +import org.sonar.api.config.internal.ConfigurationBridge; + +import static java.util.Objects.requireNonNull; + +public class ChildSettings extends Settings { + + private final Settings parentSettings; + private final Map<String, String> localProperties = new HashMap<>(); + + public ChildSettings(Settings parentSettings) { + super(parentSettings.getDefinitions(), parentSettings.getEncryption()); + this.parentSettings = parentSettings; + } + + @Override + protected Optional<String> get(String key) { + String value = localProperties.get(key); + if (value != null) { + return Optional.of(value); + } + return parentSettings.getRawString(key); + } + + @Override + protected void set(String key, String value) { + localProperties.put( + requireNonNull(key, "key can't be null"), + requireNonNull(value, "value can't be null").trim()); + } + + @Override + protected void remove(String key) { + localProperties.remove(key); + } + + /** + * Only returns the currently loaded properties. + * + * <p> + * On the Web Server, global properties are loaded lazily when requested by name. Therefor, + * this will return only global properties which have been requested using + * {@link #get(String)} at least once prior to this call. + */ + @Override + public Map<String, String> getProperties() { + // order is important. local properties override parent properties. + ImmutableMap.Builder<String, String> builder = ImmutableMap.builder(); + builder.putAll(parentSettings.getProperties()); + builder.putAll(localProperties); + return builder.build(); + } + + public Configuration asConfiguration() { + return new ConfigurationBridge(this); + } +} diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/measure/DebtRatingGridTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/measure/DebtRatingGridTest.java new file mode 100644 index 00000000000..0208ae16f02 --- /dev/null +++ b/server/sonar-server-common/src/test/java/org/sonar/server/measure/DebtRatingGridTest.java @@ -0,0 +1,100 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.measure; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.server.measure.Rating.A; +import static org.sonar.server.measure.Rating.B; +import static org.sonar.server.measure.Rating.C; +import static org.sonar.server.measure.Rating.D; +import static org.sonar.server.measure.Rating.E; + +public class DebtRatingGridTest { + + private DebtRatingGrid ratingGrid; + + @Rule + public ExpectedException throwable = ExpectedException.none(); + + @Before + public void setUp() { + double[] gridValues = new double[] {0.1, 0.2, 0.5, 1}; + ratingGrid = new DebtRatingGrid(gridValues); + } + + @Test + public void return_rating_matching_density() { + assertThat(ratingGrid.getRatingForDensity(0)).isEqualTo(A); + assertThat(ratingGrid.getRatingForDensity(0.05)).isEqualTo(A); + assertThat(ratingGrid.getRatingForDensity(0.09999999)).isEqualTo(A); + assertThat(ratingGrid.getRatingForDensity(0.1)).isEqualTo(A); + assertThat(ratingGrid.getRatingForDensity(0.15)).isEqualTo(B); + assertThat(ratingGrid.getRatingForDensity(0.2)).isEqualTo(B); + assertThat(ratingGrid.getRatingForDensity(0.25)).isEqualTo(C); + assertThat(ratingGrid.getRatingForDensity(0.5)).isEqualTo(C); + assertThat(ratingGrid.getRatingForDensity(0.65)).isEqualTo(D); + assertThat(ratingGrid.getRatingForDensity(1)).isEqualTo(D); + assertThat(ratingGrid.getRatingForDensity(1.01)).isEqualTo(E); + } + + @Test + public void density_matching_exact_grid_values() { + assertThat(ratingGrid.getRatingForDensity(0.1)).isEqualTo(A); + assertThat(ratingGrid.getRatingForDensity(0.2)).isEqualTo(B); + assertThat(ratingGrid.getRatingForDensity(0.5)).isEqualTo(C); + assertThat(ratingGrid.getRatingForDensity(1)).isEqualTo(D); + } + + @Test + public void convert_int_to_rating() { + assertThat(Rating.valueOf(1)).isEqualTo(A); + assertThat(Rating.valueOf(2)).isEqualTo(B); + assertThat(Rating.valueOf(3)).isEqualTo(C); + assertThat(Rating.valueOf(4)).isEqualTo(D); + assertThat(Rating.valueOf(5)).isEqualTo(E); + } + + @Test + public void fail_on_invalid_density() { + throwable.expect(IllegalArgumentException.class); + throwable.expectMessage("Invalid value '-1.0'"); + + ratingGrid.getRatingForDensity(-1); + } + + @Test + public void fail_to_concert_invalid_value() { + throwable.expect(IllegalArgumentException.class); + Rating.valueOf(10); + } + + @Test + public void fail_on_invalid_grid() { + throwable.expect(IllegalStateException.class); + throwable.expectMessage("Rating grid should contains 4 values"); + + ratingGrid = new DebtRatingGrid(new double[] {0.1, 0.2, 0.5}); + } +} diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/qualitygate/ShortLivingBranchQualityGateTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/qualitygate/ShortLivingBranchQualityGateTest.java new file mode 100644 index 00000000000..3f4ad722b67 --- /dev/null +++ b/server/sonar-server-common/src/test/java/org/sonar/server/qualitygate/ShortLivingBranchQualityGateTest.java @@ -0,0 +1,40 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.qualitygate; + +import org.junit.Test; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.server.qualitygate.ShortLivingBranchQualityGate.Condition; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; + +public class ShortLivingBranchQualityGateTest { + + @Test + public void defines_short_living_branches_hardcoded_quality_gate_conditions() { + assertThat(ShortLivingBranchQualityGate.CONDITIONS) + .extracting(Condition::getMetricKey, Condition::getOperator, Condition::getErrorThreshold, Condition::getWarnThreshold, Condition::isOnLeak) + .containsExactly( + tuple(CoreMetrics.OPEN_ISSUES_KEY, "GT", "0", null, false), + tuple(CoreMetrics.REOPENED_ISSUES_KEY, "GT", "0", null, false)); + } + +} diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/qualityprofile/QualityProfileTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/qualityprofile/QualityProfileTest.java new file mode 100644 index 00000000000..9642502884b --- /dev/null +++ b/server/sonar-server-common/src/test/java/org/sonar/server/qualityprofile/QualityProfileTest.java @@ -0,0 +1,80 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.qualityprofile; + +import java.util.Date; +import org.junit.Test; +import org.sonar.api.utils.DateUtils; + +import static org.assertj.core.api.Assertions.assertThat; + +public class QualityProfileTest { + + private static final String SOME_QP_KEY = "qpKey"; + private static final String SOME_QP_NAME = "qpName"; + private static final String SOME_LANGUAGE_KEY = "languageKey"; + private static final Date SOME_DATE = DateUtils.parseDateTimeQuietly("2010-05-18T15:50:45+0100"); + private static final QualityProfile QUALITY_PROFILE = new QualityProfile(SOME_QP_KEY, SOME_QP_NAME, SOME_LANGUAGE_KEY, SOME_DATE); + + @Test(expected = NullPointerException.class) + public void constructor_throws_NPE_if_qkKey_arg_is_null() { + new QualityProfile(null, SOME_QP_NAME, SOME_LANGUAGE_KEY, SOME_DATE); + } + + @Test(expected = NullPointerException.class) + public void constructor_throws_NPE_if_qpName_arg_is_null() { + new QualityProfile(SOME_QP_KEY, null, SOME_LANGUAGE_KEY, SOME_DATE); + } + + @Test(expected = NullPointerException.class) + public void constructor_throws_NPE_if_languageKey_arg_is_null() { + new QualityProfile(SOME_QP_KEY, SOME_QP_NAME, null, SOME_DATE); + } + + @Test(expected = NullPointerException.class) + public void constructor_throws_NPE_if_rulesUpdatedAt_arg_is_null() { + new QualityProfile(SOME_QP_KEY, SOME_QP_NAME, SOME_LANGUAGE_KEY, null); + } + + @Test + public void verify_properties() { + assertThat(QUALITY_PROFILE.getQpKey()).isEqualTo(SOME_QP_KEY); + assertThat(QUALITY_PROFILE.getQpName()).isEqualTo(SOME_QP_NAME); + assertThat(QUALITY_PROFILE.getLanguageKey()).isEqualTo(SOME_LANGUAGE_KEY); + assertThat(QUALITY_PROFILE.getRulesUpdatedAt()).isEqualTo(SOME_DATE); + } + + @Test + public void verify_getRulesUpdatedAt_keeps_object_immutable() { + assertThat(QUALITY_PROFILE.getRulesUpdatedAt()).isNotSameAs(SOME_DATE); + } + + @Test + public void verify_equals() { + assertThat(QUALITY_PROFILE).isEqualTo(new QualityProfile(SOME_QP_KEY, SOME_QP_NAME, SOME_LANGUAGE_KEY, SOME_DATE)); + assertThat(QUALITY_PROFILE).isEqualTo(QUALITY_PROFILE); + assertThat(QUALITY_PROFILE).isNotEqualTo(null); + } + + @Test + public void verify_toString() { + assertThat(QUALITY_PROFILE.toString()).isEqualTo("QualityProfile{key=qpKey, name=qpName, language=languageKey, rulesUpdatedAt=1274194245000}"); + } +} diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/rule/CommonRuleKeysTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/rule/CommonRuleKeysTest.java new file mode 100644 index 00000000000..45ab75f9e49 --- /dev/null +++ b/server/sonar-server-common/src/test/java/org/sonar/server/rule/CommonRuleKeysTest.java @@ -0,0 +1,39 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.rule; + +import org.junit.Test; +import org.sonar.test.TestUtils; + +import static org.assertj.core.api.Assertions.assertThat; + +public class CommonRuleKeysTest { + + @Test + public void wonderful_test_for_commonRepositoryForLang() { + assertThat(CommonRuleKeys.commonRepositoryForLang("java")).isEqualTo("common-java"); + } + + @Test + public void wonderful_test_to_verify_that_this_class_is_an_helper_class() { + assertThat(TestUtils.hasOnlyPrivateConstructors(CommonRuleKeys.class)).isTrue(); + + } +} diff --git a/server/sonar-server-common/src/test/java/org/sonar/server/setting/ChildSettingsTest.java b/server/sonar-server-common/src/test/java/org/sonar/server/setting/ChildSettingsTest.java new file mode 100644 index 00000000000..6400e8cae09 --- /dev/null +++ b/server/sonar-server-common/src/test/java/org/sonar/server/setting/ChildSettingsTest.java @@ -0,0 +1,123 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.setting; + +import java.util.Collections; +import java.util.Date; +import java.util.Optional; +import java.util.Random; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.config.PropertyDefinition; +import org.sonar.api.config.PropertyDefinitions; +import org.sonar.api.config.internal.MapSettings; + +import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; +import static org.assertj.core.api.Assertions.assertThat; + +public class ChildSettingsTest { + private static final Random RANDOM = new Random(); + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + private MapSettings parent = new MapSettings(); + private ChildSettings underTest = new ChildSettings(parent); + + @Test + public void childSettings_should_retrieve_parent_settings() { + String multipleValuesKey = randomAlphanumeric(19); + PropertyDefinition multipleValues = PropertyDefinition.builder(multipleValuesKey).multiValues(true).build(); + MapSettings parent = new MapSettings(new PropertyDefinitions(Collections.singletonList(multipleValues))); + ChildSettings underTest = new ChildSettings(parent); + + parent.setProperty(randomAlphanumeric(10), randomAlphanumeric(20)); + parent.setProperty(randomAlphanumeric(11), RANDOM.nextLong()); + parent.setProperty(randomAlphanumeric(12), RANDOM.nextDouble()); + parent.setProperty(randomAlphanumeric(13), RANDOM.nextFloat()); + parent.setProperty(randomAlphanumeric(14), RANDOM.nextBoolean()); + parent.setProperty(randomAlphanumeric(15), RANDOM.nextInt()); + parent.setProperty(randomAlphanumeric(16), new Date(RANDOM.nextInt())); + parent.setProperty(randomAlphanumeric(17), new Date(RANDOM.nextInt()), true); + parent.setProperty(randomAlphanumeric(18), new Date(RANDOM.nextInt()), false); + parent.setProperty(multipleValuesKey, new String[] { randomAlphanumeric(10), randomAlphanumeric(20) }); + + assertThat(underTest.getProperties()).isEqualTo(parent.getProperties()); + } + + @Test + public void set_will_throw_NPE_if_key_is_null() { + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("key can't be null"); + + underTest.set(null, ""); + } + + + @Test + public void set_will_throw_NPE_if_value_is_null() { + expectedException.expect(NullPointerException.class); + expectedException.expectMessage("value can't be null"); + + underTest.set(randomAlphanumeric(10), null); + } + + @Test + public void childSettings_override_parent() { + String key = randomAlphanumeric(10); + parent.setProperty(key, randomAlphanumeric(20)); + underTest.setProperty(key, randomAlphanumeric(10)); + + assertThat(underTest.get(key)).isNotEqualTo(parent.getString(key)); + } + + @Test + public void remove_should_not_throw_exception_if_key_is_not_present() { + underTest.remove(randomAlphanumeric(90)); + } + + @Test + public void remove_should_remove_value() { + String key = randomAlphanumeric(10); + String childValue = randomAlphanumeric(10); + + underTest.set(key, childValue); + assertThat(underTest.get(key)).isEqualTo(Optional.of(childValue)); + + underTest.remove(key); + assertThat(underTest.get(key)).isEqualTo(Optional.empty()); + } + + @Test + public void remove_should_retrieve_parent_value() { + String key = randomAlphanumeric(10); + String childValue = randomAlphanumeric(10); + String parentValue = randomAlphanumeric(10); + + parent.setProperty(key, parentValue); + underTest.set(key, childValue); + assertThat(underTest.get(key)).isEqualTo(Optional.of(childValue)); + + underTest.remove(key); + assertThat(underTest.get(key)).isEqualTo(Optional.of(parentValue)); + } + +} |