From: Sébastien Lesaint Date: Thu, 21 Jun 2018 09:27:56 +0000 (+0200) Subject: fix wrong dependencies onto package computation.task.projectanalysis X-Git-Tag: 7.5~932 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=abac7619c39e0e24aa86bb1150ce00b4063fa241;p=sonarqube.git fix wrong dependencies onto package computation.task.projectanalysis --- diff --git a/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java b/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java index 061785baef5..6039f9f9d26 100644 --- a/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java +++ b/server/sonar-ce/src/main/java/org/sonar/ce/container/ComputeEngineContainerImpl.java @@ -57,7 +57,7 @@ import org.sonar.ce.platform.CECoreExtensionsInstaller; import org.sonar.ce.platform.ComputeEngineExtensionInstaller; import org.sonar.ce.queue.CeQueueCleaner; import org.sonar.ce.queue.PurgeCeActivities; -import org.sonar.ce.settings.ProjectConfigurationFactory; +import org.sonar.server.computation.task.projectanalysis.analysis.ProjectConfigurationFactory; import org.sonar.ce.taskprocessor.CeProcessingScheduler; import org.sonar.ce.taskprocessor.CeTaskProcessorModule; import org.sonar.ce.user.CeUserSession; diff --git a/server/sonar-server/src/main/java/org/sonar/ce/settings/ProjectConfigurationFactory.java b/server/sonar-server/src/main/java/org/sonar/ce/settings/ProjectConfigurationFactory.java deleted file mode 100644 index c750ecabe2b..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/ce/settings/ProjectConfigurationFactory.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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.ce.settings; - -import org.sonar.api.ce.ComputeEngineSide; -import org.sonar.api.config.Configuration; -import org.sonar.api.config.Settings; -import org.sonar.api.config.internal.ConfigurationBridge; -import org.sonar.db.DbClient; -import org.sonar.db.component.BranchType; -import org.sonar.server.computation.task.projectanalysis.analysis.Branch; -import org.sonar.server.settings.ChildSettings; - -import static org.sonar.db.component.ComponentDto.generateBranchKey; -import static org.sonar.db.component.ComponentDto.generatePullRequestKey; - -@ComputeEngineSide -public class ProjectConfigurationFactory { - - private final Settings globalSettings; - private final DbClient dbClient; - - public ProjectConfigurationFactory(Settings globalSettings, DbClient dbClient) { - this.globalSettings = globalSettings; - this.dbClient = dbClient; - } - - public Configuration newProjectConfiguration(String projectKey, Branch branch) { - Settings projectSettings = new ChildSettings(globalSettings); - addSettings(projectSettings, projectKey); - if (branch.getType() == BranchType.PULL_REQUEST) { - addSettings(projectSettings, generatePullRequestKey(projectKey, branch.getPullRequestKey())); - } else { - addSettings(projectSettings, generateBranchKey(projectKey, branch.getName())); - } - return new ConfigurationBridge(projectSettings); - } - - private void addSettings(Settings settings, String componentDbKey) { - dbClient.propertiesDao() - .selectProjectProperties(componentDbKey) - .forEach(property -> settings.setProperty(property.getKey(), property.getValue())); - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/badge/ws/MeasureAction.java b/server/sonar-server/src/main/java/org/sonar/server/badge/ws/MeasureAction.java index 462fcd9b90c..645fe3cc9a8 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/badge/ws/MeasureAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/badge/ws/MeasureAction.java @@ -38,7 +38,7 @@ import org.sonar.db.component.ComponentDto; import org.sonar.db.measure.LiveMeasureDto; import org.sonar.db.metric.MetricDto; import org.sonar.server.badge.ws.SvgGenerator.Color; -import org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating; +import org.sonar.server.measure.Rating; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; @@ -67,12 +67,12 @@ import static org.sonar.server.badge.ws.ETagUtils.getETag; import static org.sonar.server.badge.ws.SvgFormatter.formatDuration; import static org.sonar.server.badge.ws.SvgFormatter.formatNumeric; import static org.sonar.server.badge.ws.SvgFormatter.formatPercent; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.A; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.B; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.C; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.D; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.E; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.valueOf; +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; +import static org.sonar.server.measure.Rating.valueOf; import static org.sonarqube.ws.MediaTypes.SVG; public class MeasureAction implements ProjectBadgesWsAction { diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/analysis/ProjectConfigurationFactory.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/analysis/ProjectConfigurationFactory.java new file mode 100644 index 00000000000..4cb040efd85 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/analysis/ProjectConfigurationFactory.java @@ -0,0 +1,60 @@ +/* + * 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.computation.task.projectanalysis.analysis; + +import org.sonar.api.ce.ComputeEngineSide; +import org.sonar.api.config.Configuration; +import org.sonar.api.config.Settings; +import org.sonar.api.config.internal.ConfigurationBridge; +import org.sonar.db.DbClient; +import org.sonar.db.component.BranchType; +import org.sonar.server.settings.ChildSettings; + +import static org.sonar.db.component.ComponentDto.generateBranchKey; +import static org.sonar.db.component.ComponentDto.generatePullRequestKey; + +@ComputeEngineSide +public class ProjectConfigurationFactory { + + private final Settings globalSettings; + private final DbClient dbClient; + + public ProjectConfigurationFactory(Settings globalSettings, DbClient dbClient) { + this.globalSettings = globalSettings; + this.dbClient = dbClient; + } + + public Configuration newProjectConfiguration(String projectKey, Branch branch) { + Settings projectSettings = new ChildSettings(globalSettings); + addSettings(projectSettings, projectKey); + if (branch.getType() == BranchType.PULL_REQUEST) { + addSettings(projectSettings, generatePullRequestKey(projectKey, branch.getPullRequestKey())); + } else { + addSettings(projectSettings, generateBranchKey(projectKey, branch.getName())); + } + return new ConfigurationBridge(projectSettings); + } + + private void addSettings(Settings settings, String componentDbKey) { + dbClient.propertiesDao() + .selectProjectProperties(componentDbKey) + .forEach(property -> settings.setProperty(property.getKey(), property.getValue())); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/component/ConfigurationRepositoryImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/component/ConfigurationRepositoryImpl.java index 4383d76ba7a..736bf014cfa 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/component/ConfigurationRepositoryImpl.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/component/ConfigurationRepositoryImpl.java @@ -22,7 +22,7 @@ package org.sonar.server.computation.task.projectanalysis.component; import com.google.common.base.Supplier; import com.google.common.base.Suppliers; import org.sonar.api.config.Configuration; -import org.sonar.ce.settings.ProjectConfigurationFactory; +import org.sonar.server.computation.task.projectanalysis.analysis.ProjectConfigurationFactory; import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolder; /** diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/formula/counter/RatingValue.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/formula/counter/RatingValue.java index 03077e12a64..39ce513fd44 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/formula/counter/RatingValue.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/formula/counter/RatingValue.java @@ -20,7 +20,7 @@ package org.sonar.server.computation.task.projectanalysis.formula.counter; import javax.annotation.Nullable; -import org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating; +import org.sonar.server.measure.Rating; /** * Convenience class wrapping a rating to compute the value and know it is has ever been set. diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/NewExternalRule.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/NewExternalRule.java deleted file mode 100644 index 1be91e3b605..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/NewExternalRule.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * 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.computation.task.projectanalysis.issue; - -import java.util.Collections; -import java.util.Objects; -import java.util.Set; -import javax.annotation.concurrent.Immutable; -import org.sonar.api.rule.RuleKey; -import org.sonar.api.rule.RuleStatus; -import org.sonar.api.rules.RuleType; -import org.sonar.api.server.debt.DebtRemediationFunction; - -@Immutable -public class NewExternalRule implements Rule { - private final RuleKey key; - private final String name; - private final String pluginKey; - - private NewExternalRule(Builder builder) { - Objects.requireNonNull(builder.key, "'key' not expected to be null for an external rule"); - this.key = builder.key; - this.pluginKey = builder.pluginKey; - this.name = builder.name; - } - - @Override - public int getId() { - return 0; - } - - @Override - public RuleKey getKey() { - return key; - } - - @Override - public String getName() { - return name; - } - - @Override - public RuleStatus getStatus() { - return RuleStatus.defaultStatus(); - } - - @Override - public RuleType getType() { - return null; - } - - @Override - public boolean isExternal() { - return true; - } - - @Override - public Set getTags() { - return Collections.emptySet(); - } - - @Override - public DebtRemediationFunction getRemediationFunction() { - return null; - } - - @Override - public String getPluginKey() { - return pluginKey; - } - - public static class Builder { - private RuleKey key; - private String pluginKey; - private String name; - - public Builder setKey(RuleKey key) { - this.key = key; - return this; - } - - public Builder setName(String name) { - this.name = name; - return this; - } - - public String name() { - return name; - } - - public NewExternalRule build() { - return new NewExternalRule(this); - } - - public Builder setPluginKey(String pluginKey) { - this.pluginKey = pluginKey; - return this; - } - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/RuleRepository.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/RuleRepository.java index adb1dd8d18e..1831b74b8a1 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/RuleRepository.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/RuleRepository.java @@ -23,6 +23,7 @@ import java.util.Optional; import java.util.function.Supplier; import org.sonar.api.rule.RuleKey; import org.sonar.db.DbSession; +import org.sonar.server.rule.NewExternalRule; /** * Repository of every rule in DB (including manual rules) whichever their status. diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/RuleRepositoryImpl.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/RuleRepositoryImpl.java index b29dea960cd..1c3f13cf700 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/RuleRepositoryImpl.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/RuleRepositoryImpl.java @@ -20,12 +20,17 @@ package org.sonar.server.computation.task.projectanalysis.issue; import com.google.common.collect.Multimap; +import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.function.Supplier; import javax.annotation.CheckForNull; import org.sonar.api.rule.RuleKey; +import org.sonar.api.rule.RuleStatus; +import org.sonar.api.rules.RuleType; +import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.core.util.stream.MoreCollectors; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -33,6 +38,7 @@ import org.sonar.db.rule.DeprecatedRuleKeyDto; import org.sonar.db.rule.RuleDto; import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolder; import org.sonar.server.rule.ExternalRuleCreator; +import org.sonar.server.rule.NewExternalRule; import static com.google.common.base.Preconditions.checkArgument; import static java.util.Objects.requireNonNull; @@ -58,7 +64,7 @@ public class RuleRepositoryImpl implements RuleRepository { ensureInitialized(); if (!rulesByKey.containsKey(ruleKey)) { - rulesByKey.computeIfAbsent(ruleKey, s -> ruleSupplier.get()); + rulesByKey.computeIfAbsent(ruleKey, s -> new ExternalRuleWrapper(ruleSupplier.get())); } } @@ -67,12 +73,12 @@ public class RuleRepositoryImpl implements RuleRepository { ensureInitialized(); rulesByKey.values().stream() - .filter(NewExternalRule.class::isInstance) - .forEach(extRule -> persistAndIndex(dbSession, (NewExternalRule) extRule)); + .filter(ExternalRuleWrapper.class::isInstance) + .forEach(extRule -> persistAndIndex(dbSession, (ExternalRuleWrapper) extRule)); } - private void persistAndIndex(DbSession dbSession, NewExternalRule external) { - Rule rule = creator.persistAndIndex(dbSession, external); + private void persistAndIndex(DbSession dbSession, ExternalRuleWrapper external) { + Rule rule = new RuleImpl(creator.persistAndIndex(dbSession, external.getDelegate())); rulesById.put(rule.getId(), rule); rulesByKey.put(external.getKey(), rule); } @@ -139,4 +145,63 @@ public class RuleRepositoryImpl implements RuleRepository { } } + private static class ExternalRuleWrapper implements Rule { + private final NewExternalRule externalRule; + + private ExternalRuleWrapper(NewExternalRule externalRule) { + this.externalRule = externalRule; + } + + public NewExternalRule getDelegate() { + return externalRule; + } + + @Override + public int getId() { + return 0; + } + + @Override + public RuleKey getKey() { + return externalRule.getKey(); + } + + @Override + public String getName() { + return externalRule.getName(); + } + + @Override + public RuleStatus getStatus() { + return RuleStatus.defaultStatus(); + } + + @Override + @CheckForNull + public RuleType getType() { + return null; + } + + @Override + public boolean isExternal() { + return true; + } + + @Override + public Set getTags() { + return Collections.emptySet(); + } + + @CheckForNull + @Override + public DebtRemediationFunction getRemediationFunction() { + return null; + } + + @CheckForNull + @Override + public String getPluginKey() { + return externalRule.getPluginKey(); + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/TrackerRawInputFactory.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/TrackerRawInputFactory.java index cb5b312638d..d3e9d2f157a 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/TrackerRawInputFactory.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/TrackerRawInputFactory.java @@ -46,6 +46,7 @@ import org.sonar.server.computation.task.projectanalysis.issue.filter.IssueFilte import org.sonar.server.computation.task.projectanalysis.qualityprofile.ActiveRulesHolder; import org.sonar.server.computation.task.projectanalysis.source.SourceLinesHashRepository; import org.sonar.server.rule.CommonRuleKeys; +import org.sonar.server.rule.NewExternalRule; import static org.apache.commons.lang.StringUtils.isNotEmpty; diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/measure/PostMeasuresComputationCheck.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/measure/PostMeasuresComputationCheck.java new file mode 100644 index 00000000000..967778694b7 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/measure/PostMeasuresComputationCheck.java @@ -0,0 +1,58 @@ +/* + * 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.computation.task.projectanalysis.measure; + +import org.sonar.api.ExtensionPoint; +import org.sonar.api.ce.ComputeEngineSide; +import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolder; + +/** + * Extension point that is called during processing of a task + * by {@link PostMeasuresComputationChecksStep}. + * + * It is stateless, the same instance is reused for all tasks. + * As a consequence Compute Engine task components can't be injected + * as dependencies. + */ +@ComputeEngineSide +@ExtensionPoint +public interface PostMeasuresComputationCheck { + + /** + * This method can make the task fail by throwing a {@link RuntimeException} + */ + void onCheck(Context context); + + interface Context { + + /** + * Return the project UUID, as returned by {@link AnalysisMetadataHolder#getProject()#getUuid()}. + * + * It means that when analyzing a non main-branch, it will be the UUID of the project, not the UUId of the branch/pull-request. + */ + String getProjectUuid(); + + /** + * Return the ncloc computed for the current analysis + */ + int getNcloc(); + } + +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/measure/PostMeasuresComputationChecksStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/measure/PostMeasuresComputationChecksStep.java new file mode 100644 index 00000000000..b03e3e39ba1 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/measure/PostMeasuresComputationChecksStep.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.computation.task.projectanalysis.measure; + +import com.google.common.base.Optional; +import org.sonar.api.ce.ComputeEngineSide; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolder; +import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolder; +import org.sonar.server.computation.task.projectanalysis.metric.Metric; +import org.sonar.server.computation.task.projectanalysis.metric.MetricRepository; +import org.sonar.server.computation.task.step.ComputationStep; + +/** + * Execute {@link PostMeasuresComputationCheck} instances in no specific order. + * If an extension fails (throws an exception), consecutive extensions + * won't be called. + */ +@ComputeEngineSide +public class PostMeasuresComputationChecksStep implements ComputationStep { + + private final TreeRootHolder treeRootHolder; + private final MetricRepository metricRepository; + private final MeasureRepository measureRepository; + private final AnalysisMetadataHolder analysisMetadataHolder; + private final PostMeasuresComputationCheck[] extensions; + + public PostMeasuresComputationChecksStep(TreeRootHolder treeRootHolder, MetricRepository metricRepository, MeasureRepository measureRepository, + AnalysisMetadataHolder analysisMetadataHolder, + PostMeasuresComputationCheck[] extensions) { + this.treeRootHolder = treeRootHolder; + this.metricRepository = metricRepository; + this.measureRepository = measureRepository; + this.analysisMetadataHolder = analysisMetadataHolder; + this.extensions = extensions; + } + + /** + * Used when zero {@link PostMeasuresComputationCheck} are registered into container. + */ + public PostMeasuresComputationChecksStep(TreeRootHolder treeRootHolder, MetricRepository metricRepository, MeasureRepository measureRepository, + AnalysisMetadataHolder analysisMetadataHolder) { + this(treeRootHolder, metricRepository, measureRepository, analysisMetadataHolder, new PostMeasuresComputationCheck[0]); + } + + @Override + public void execute() { + PostMeasuresComputationCheck.Context context = new ContextImpl(); + for (PostMeasuresComputationCheck extension : extensions) { + extension.onCheck(context); + } + } + + @Override + public String getDescription() { + return "Checks executed after computation of measures"; + } + + private class ContextImpl implements PostMeasuresComputationCheck.Context { + + @Override + public String getProjectUuid() { + return analysisMetadataHolder.getProject().getUuid(); + } + + @Override + public int getNcloc() { + Metric nclocMetric = metricRepository.getByKey(CoreMetrics.NCLOC_KEY); + Optional nclocMeasure = measureRepository.getRawMeasure(treeRootHolder.getRoot(), nclocMetric); + return nclocMeasure.isPresent() ? nclocMeasure.get().getIntValue() : 0; + } + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/DebtRatingGrid.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/DebtRatingGrid.java deleted file mode 100644 index 30e0cf2519e..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/DebtRatingGrid.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 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.computation.task.projectanalysis.qualitymodel; - -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.computation.task.projectanalysis.qualitymodel.Rating.A; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.B; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.C; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.D; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.E; - -public class DebtRatingGrid { - - private final double[] gridValues; - private final EnumMap 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 buildRatingBounds(double[] gridValues) { - checkState(gridValues.length == 4, "Rating grid should contains 4 values"); - EnumMap 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 - 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/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitor.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitor.java index e707df6d9fc..ae5deada236 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitor.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitor.java @@ -29,6 +29,7 @@ import org.sonar.server.computation.task.projectanalysis.measure.Measure; import org.sonar.server.computation.task.projectanalysis.measure.MeasureRepository; import org.sonar.server.computation.task.projectanalysis.metric.Metric; import org.sonar.server.computation.task.projectanalysis.metric.MetricRepository; +import org.sonar.server.measure.Rating; import static org.sonar.api.measures.CoreMetrics.DEVELOPMENT_COST_KEY; import static org.sonar.api.measures.CoreMetrics.EFFORT_TO_REACH_MAINTAINABILITY_RATING_A_KEY; diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/NewReliabilityAndSecurityRatingMeasuresVisitor.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/NewReliabilityAndSecurityRatingMeasuresVisitor.java index b683fab8ceb..9b518b502b8 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/NewReliabilityAndSecurityRatingMeasuresVisitor.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/NewReliabilityAndSecurityRatingMeasuresVisitor.java @@ -33,6 +33,7 @@ import org.sonar.server.computation.task.projectanalysis.metric.Metric; import org.sonar.server.computation.task.projectanalysis.metric.MetricRepository; import org.sonar.server.computation.task.projectanalysis.period.Period; import org.sonar.server.computation.task.projectanalysis.period.PeriodHolder; +import org.sonar.server.measure.Rating; import static org.sonar.api.measures.CoreMetrics.NEW_RELIABILITY_RATING_KEY; import static org.sonar.api.measures.CoreMetrics.NEW_SECURITY_RATING_KEY; @@ -48,11 +49,11 @@ import static org.sonar.server.computation.task.projectanalysis.component.Compon import static org.sonar.server.computation.task.projectanalysis.component.CrawlerDepthLimit.LEAVES; import static org.sonar.server.computation.task.projectanalysis.measure.Measure.newMeasureBuilder; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.A; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.B; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.C; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.D; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.E; +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; /** * Compute following measures : diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/Rating.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/Rating.java deleted file mode 100644 index 82e37937c34..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/Rating.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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.computation.task.projectanalysis.qualitymodel; - -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 RATING_BY_SEVERITY = ImmutableMap.of( - BLOCKER, E, - CRITICAL, D, - MAJOR, C, - MINOR, B, - INFO, A); -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/RatingSettings.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/RatingSettings.java index 023875ff2b8..8be66d201b0 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/RatingSettings.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/RatingSettings.java @@ -27,6 +27,7 @@ import javax.annotation.concurrent.Immutable; import org.sonar.api.ce.ComputeEngineSide; import org.sonar.api.config.Configuration; import org.sonar.api.utils.MessageException; +import org.sonar.server.measure.DebtRatingGrid; import static java.lang.String.format; import static org.sonar.api.CoreProperties.DEVELOPMENT_COST; diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitor.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitor.java index b9d55d835ff..673129894c0 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitor.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitor.java @@ -29,6 +29,7 @@ import org.sonar.server.computation.task.projectanalysis.issue.ComponentIssuesRe import org.sonar.server.computation.task.projectanalysis.measure.MeasureRepository; import org.sonar.server.computation.task.projectanalysis.metric.Metric; import org.sonar.server.computation.task.projectanalysis.metric.MetricRepository; +import org.sonar.server.measure.Rating; import static org.sonar.api.measures.CoreMetrics.RELIABILITY_RATING_KEY; import static org.sonar.api.measures.CoreMetrics.SECURITY_RATING_KEY; @@ -37,7 +38,7 @@ import static org.sonar.api.rules.RuleType.VULNERABILITY; import static org.sonar.server.computation.task.projectanalysis.component.ComponentVisitor.Order.POST_ORDER; import static org.sonar.server.computation.task.projectanalysis.component.CrawlerDepthLimit.FILE; import static org.sonar.server.computation.task.projectanalysis.measure.Measure.newMeasureBuilder; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.RATING_BY_SEVERITY; +import static org.sonar.server.measure.Rating.RATING_BY_SEVERITY; /** * Compute following measures for projects and descendants: diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/ReportComputationSteps.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/ReportComputationSteps.java index e75c98dba74..b28b1a144bd 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/ReportComputationSteps.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/step/ReportComputationSteps.java @@ -25,7 +25,7 @@ import org.sonar.server.computation.task.container.TaskContainer; import org.sonar.server.computation.task.projectanalysis.filemove.FileMoveDetectionStep; import org.sonar.server.computation.task.step.ComputationStep; import org.sonar.server.computation.task.step.ExecuteStatelessInitExtensionsStep; -import org.sonar.server.computation.task.step.PostMeasuresComputationChecksStep; +import org.sonar.server.computation.task.projectanalysis.measure.PostMeasuresComputationChecksStep; /** * Ordered list of steps classes and instances to be executed for batch processing diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/step/ComputationStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/step/ComputationStep.java index c65b3f706bb..f8fd66fe961 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/step/ComputationStep.java +++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/step/ComputationStep.java @@ -19,10 +19,9 @@ */ package org.sonar.server.computation.task.step; -import org.sonar.server.computation.task.projectanalysis.step.ReportComputationSteps; - /** - * Implementations must be declared into {@link ReportComputationSteps#orderedStepClasses()} + * A way of splitting the processing of a task into smaller items which can be executed sequencially + * by {@link ComputationStepExecutor}. */ public interface ComputationStep { diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/step/PostMeasuresComputationCheck.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/step/PostMeasuresComputationCheck.java deleted file mode 100644 index 2ba9c1ca31d..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/step/PostMeasuresComputationCheck.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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.computation.task.step; - -import org.sonar.api.ExtensionPoint; -import org.sonar.api.ce.ComputeEngineSide; -import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolder; - -/** - * Extension point that is called during processing of a task - * by {@link PostMeasuresComputationChecksStep}. - * - * It is stateless, the same instance is reused for all tasks. - * As a consequence Compute Engine task components can't be injected - * as dependencies. - */ -@ComputeEngineSide -@ExtensionPoint -public interface PostMeasuresComputationCheck { - - /** - * This method can make the task fail by throwing a {@link RuntimeException} - */ - void onCheck(Context context); - - interface Context { - - /** - * Return the project UUID, as returned by {@link AnalysisMetadataHolder#getProject()#getUuid()}. - * - * It means that when analyzing a non main-branch, it will be the UUID of the project, not the UUId of the branch/pull-request. - */ - String getProjectUuid(); - - /** - * Return the ncloc computed for the current analysis - */ - int getNcloc(); - } - -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/step/PostMeasuresComputationChecksStep.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/step/PostMeasuresComputationChecksStep.java deleted file mode 100644 index 844643fa22e..00000000000 --- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/step/PostMeasuresComputationChecksStep.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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.computation.task.step; - -import com.google.common.base.Optional; -import org.sonar.api.ce.ComputeEngineSide; -import org.sonar.api.measures.CoreMetrics; -import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolder; -import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolder; -import org.sonar.server.computation.task.projectanalysis.measure.Measure; -import org.sonar.server.computation.task.projectanalysis.measure.MeasureRepository; -import org.sonar.server.computation.task.projectanalysis.metric.Metric; -import org.sonar.server.computation.task.projectanalysis.metric.MetricRepository; - -/** - * Execute {@link PostMeasuresComputationCheck} instances in no specific order. - * If an extension fails (throws an exception), consecutive extensions - * won't be called. - */ -@ComputeEngineSide -public class PostMeasuresComputationChecksStep implements ComputationStep { - - private final TreeRootHolder treeRootHolder; - private final MetricRepository metricRepository; - private final MeasureRepository measureRepository; - private final AnalysisMetadataHolder analysisMetadataHolder; - private final PostMeasuresComputationCheck[] extensions; - - public PostMeasuresComputationChecksStep(TreeRootHolder treeRootHolder, MetricRepository metricRepository, MeasureRepository measureRepository, - AnalysisMetadataHolder analysisMetadataHolder, - PostMeasuresComputationCheck[] extensions) { - this.treeRootHolder = treeRootHolder; - this.metricRepository = metricRepository; - this.measureRepository = measureRepository; - this.analysisMetadataHolder = analysisMetadataHolder; - this.extensions = extensions; - } - - /** - * Used when zero {@link PostMeasuresComputationCheck} are registered into container. - */ - public PostMeasuresComputationChecksStep(TreeRootHolder treeRootHolder, MetricRepository metricRepository, MeasureRepository measureRepository, - AnalysisMetadataHolder analysisMetadataHolder) { - this(treeRootHolder, metricRepository, measureRepository, analysisMetadataHolder, new PostMeasuresComputationCheck[0]); - } - - @Override - public void execute() { - PostMeasuresComputationCheck.Context context = new ContextImpl(); - for (PostMeasuresComputationCheck extension : extensions) { - extension.onCheck(context); - } - } - - @Override - public String getDescription() { - return "Checks executed after computation of measures"; - } - - private class ContextImpl implements PostMeasuresComputationCheck.Context { - - @Override - public String getProjectUuid() { - return analysisMetadataHolder.getProject().getUuid(); - } - - @Override - public int getNcloc() { - Metric nclocMetric = metricRepository.getByKey(CoreMetrics.NCLOC_KEY); - Optional nclocMeasure = measureRepository.getRawMeasure(treeRootHolder.getRoot(), nclocMetric); - return nclocMeasure.isPresent() ? nclocMeasure.get().getIntValue() : 0; - } - } -} diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/DebtRatingGrid.java b/server/sonar-server/src/main/java/org/sonar/server/measure/DebtRatingGrid.java new file mode 100644 index 00000000000..faac02fc016 --- /dev/null +++ b/server/sonar-server/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 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 buildRatingBounds(double[] gridValues) { + checkState(gridValues.length == 4, "Rating grid should contains 4 values"); + EnumMap 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/src/main/java/org/sonar/server/measure/Rating.java b/server/sonar-server/src/main/java/org/sonar/server/measure/Rating.java new file mode 100644 index 00000000000..873f682f998 --- /dev/null +++ b/server/sonar-server/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 RATING_BY_SEVERITY = ImmutableMap.of( + BLOCKER, E, + CRITICAL, D, + MAJOR, C, + MINOR, B, + INFO, A); +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/live/IssueMetricFormula.java b/server/sonar-server/src/main/java/org/sonar/server/measure/live/IssueMetricFormula.java index 521e65be629..9b3630e7519 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/measure/live/IssueMetricFormula.java +++ b/server/sonar-server/src/main/java/org/sonar/server/measure/live/IssueMetricFormula.java @@ -24,8 +24,8 @@ import java.util.Optional; import java.util.function.BiConsumer; import org.sonar.api.measures.Metric; import org.sonar.db.component.ComponentDto; -import org.sonar.server.computation.task.projectanalysis.qualitymodel.DebtRatingGrid; -import org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating; +import org.sonar.server.measure.DebtRatingGrid; +import org.sonar.server.measure.Rating; import static java.util.Collections.emptyList; diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/live/IssueMetricFormulaFactoryImpl.java b/server/sonar-server/src/main/java/org/sonar/server/measure/live/IssueMetricFormulaFactoryImpl.java index 4044e5d7ea4..def6ce168c0 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/measure/live/IssueMetricFormulaFactoryImpl.java +++ b/server/sonar-server/src/main/java/org/sonar/server/measure/live/IssueMetricFormulaFactoryImpl.java @@ -27,10 +27,10 @@ import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.Metric; import org.sonar.api.rule.Severity; import org.sonar.api.rules.RuleType; -import org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating; +import org.sonar.server.measure.Rating; import static java.util.Arrays.asList; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.RATING_BY_SEVERITY; +import static org.sonar.server.measure.Rating.RATING_BY_SEVERITY; public class IssueMetricFormulaFactoryImpl implements IssueMetricFormulaFactory { diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/live/LiveMeasureComputerImpl.java b/server/sonar-server/src/main/java/org/sonar/server/measure/live/LiveMeasureComputerImpl.java index 9974d3eca3c..7fc29cb154d 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/measure/live/LiveMeasureComputerImpl.java +++ b/server/sonar-server/src/main/java/org/sonar/server/measure/live/LiveMeasureComputerImpl.java @@ -39,8 +39,8 @@ import org.sonar.db.component.SnapshotDto; import org.sonar.db.measure.LiveMeasureDto; import org.sonar.db.metric.MetricDto; import org.sonar.db.organization.OrganizationDto; -import org.sonar.server.computation.task.projectanalysis.qualitymodel.DebtRatingGrid; -import org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating; +import org.sonar.server.measure.DebtRatingGrid; +import org.sonar.server.measure.Rating; import org.sonar.server.es.ProjectIndexer; import org.sonar.server.es.ProjectIndexers; import org.sonar.server.qualitygate.EvaluatedQualityGate; diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/live/MeasureMatrix.java b/server/sonar-server/src/main/java/org/sonar/server/measure/live/MeasureMatrix.java index 0dad8f5b745..353dd117ff9 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/measure/live/MeasureMatrix.java +++ b/server/sonar-server/src/main/java/org/sonar/server/measure/live/MeasureMatrix.java @@ -36,7 +36,7 @@ import javax.annotation.Nullable; import org.sonar.db.component.ComponentDto; import org.sonar.db.measure.LiveMeasureDto; import org.sonar.db.metric.MetricDto; -import org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating; +import org.sonar.server.measure.Rating; import static com.google.common.base.Preconditions.checkArgument; import static java.util.Objects.requireNonNull; diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/package-info.java b/server/sonar-server/src/main/java/org/sonar/server/measure/package-info.java new file mode 100644 index 00000000000..16ec2482de6 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/measure/package-info.java @@ -0,0 +1,23 @@ +/* + * 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. + */ +@ParametersAreNonnullByDefault +package org.sonar.server.measure; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java index 4cf3c4492d0..3b9dc86758c 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java @@ -30,7 +30,6 @@ import org.sonar.api.rules.XMLRuleParser; import org.sonar.api.server.rule.RulesDefinitionXmlLoader; import org.sonar.ce.CeModule; import org.sonar.ce.notification.ReportAnalysisFailureNotificationModule; -import org.sonar.ce.settings.ProjectConfigurationFactory; import org.sonar.core.component.DefaultResourceTypes; import org.sonar.core.extension.CoreExtensionsInstaller; import org.sonar.core.platform.ComponentContainer; @@ -551,7 +550,6 @@ public class PlatformLevel4 extends PlatformLevel { PlatformEditionProvider.class, InternalPropertiesImpl.class, - ProjectConfigurationFactory.class, // UI NavigationWsModule.class, diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateConditionsUpdater.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateConditionsUpdater.java index 0a70ed55ad6..40e26606a8e 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateConditionsUpdater.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QualityGateConditionsUpdater.java @@ -34,7 +34,7 @@ import org.sonar.db.DbSession; import org.sonar.db.metric.MetricDto; import org.sonar.db.qualitygate.QualityGateConditionDto; import org.sonar.db.qualitygate.QualityGateDto; -import org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating; +import org.sonar.server.measure.Rating; import org.sonar.server.exceptions.NotFoundException; import static com.google.common.base.Strings.isNullOrEmpty; @@ -46,7 +46,7 @@ import static java.util.Arrays.stream; import static org.sonar.api.measures.Metric.ValueType.RATING; import static org.sonar.api.measures.Metric.ValueType.valueOf; import static org.sonar.db.qualitygate.QualityGateConditionDto.isOperatorAllowed; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.E; +import static org.sonar.server.measure.Rating.E; import static org.sonar.server.qualitygate.ValidRatingMetrics.isCoreRatingMetric; import static org.sonar.server.ws.WsUtils.checkRequest; diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/RegisterQualityGates.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/RegisterQualityGates.java index 3effb8aa841..5b9a6517850 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/RegisterQualityGates.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/RegisterQualityGates.java @@ -39,7 +39,7 @@ import org.sonar.db.qualitygate.QualityGateConditionDao; import org.sonar.db.qualitygate.QualityGateConditionDto; import org.sonar.db.qualitygate.QualityGateDao; import org.sonar.db.qualitygate.QualityGateDto; -import org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating; +import org.sonar.server.measure.Rating; import static java.util.Arrays.asList; import static java.util.stream.Collectors.toMap; diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/ExternalRuleCreator.java b/server/sonar-server/src/main/java/org/sonar/server/rule/ExternalRuleCreator.java index 30ee1919563..9044ebff3a1 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/rule/ExternalRuleCreator.java +++ b/server/sonar-server/src/main/java/org/sonar/server/rule/ExternalRuleCreator.java @@ -24,9 +24,7 @@ import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.rule.RuleDao; import org.sonar.db.rule.RuleDefinitionDto; -import org.sonar.server.computation.task.projectanalysis.issue.NewExternalRule; -import org.sonar.server.computation.task.projectanalysis.issue.Rule; -import org.sonar.server.computation.task.projectanalysis.issue.RuleImpl; +import org.sonar.db.rule.RuleDto; import org.sonar.server.rule.index.RuleIndexer; import static org.sonar.api.rule.RuleStatus.READY; @@ -48,21 +46,21 @@ public class ExternalRuleCreator { * Persists a rule in the DB and indexes it. * @return the rule that was inserted in the DB, which includes the generated ID. */ - public Rule persistAndIndex(DbSession dbSession, NewExternalRule external) { + public RuleDto persistAndIndex(DbSession dbSession, NewExternalRule external) { RuleDao dao = dbClient.ruleDao(); dao.insert(dbSession, new RuleDefinitionDto() .setRuleKey(external.getKey()) .setPluginKey(external.getPluginKey()) - .setIsExternal(external.isExternal()) + .setIsExternal(true) .setName(external.getName()) .setScope(ALL) .setStatus(READY) .setCreatedAt(system2.now()) .setUpdatedAt(system2.now())); - Rule newRule = new RuleImpl(dao.selectOrFailByKey(dbSession, external.getKey())); - ruleIndexer.commitAndIndex(dbSession, newRule.getId()); - return newRule; + RuleDto ruleDto = dao.selectOrFailByKey(dbSession, external.getKey()); + ruleIndexer.commitAndIndex(dbSession, ruleDto.getId()); + return ruleDto; } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/rule/NewExternalRule.java b/server/sonar-server/src/main/java/org/sonar/server/rule/NewExternalRule.java new file mode 100644 index 00000000000..a968a43d7ac --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/rule/NewExternalRule.java @@ -0,0 +1,79 @@ +/* + * 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 java.util.Objects; +import javax.annotation.concurrent.Immutable; +import org.sonar.api.rule.RuleKey; + +@Immutable +public class NewExternalRule { + private final RuleKey key; + private final String name; + private final String pluginKey; + + private NewExternalRule(Builder builder) { + Objects.requireNonNull(builder.key, "'key' not expected to be null for an external rule"); + this.key = builder.key; + this.pluginKey = builder.pluginKey; + this.name = builder.name; + } + + public RuleKey getKey() { + return key; + } + + public String getName() { + return name; + } + + public String getPluginKey() { + return pluginKey; + } + + public static class Builder { + private RuleKey key; + private String pluginKey; + private String name; + + public Builder setKey(RuleKey key) { + this.key = key; + return this; + } + + public Builder setName(String name) { + this.name = name; + return this; + } + + public String name() { + return name; + } + + public NewExternalRule build() { + return new NewExternalRule(this); + } + + public Builder setPluginKey(String pluginKey) { + this.pluginKey = pluginKey; + return this; + } + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/ce/settings/ProjectConfigurationFactoryTest.java b/server/sonar-server/src/test/java/org/sonar/ce/settings/ProjectConfigurationFactoryTest.java deleted file mode 100644 index b6f396ba539..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/ce/settings/ProjectConfigurationFactoryTest.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * 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.ce.settings; - -import org.junit.Rule; -import org.junit.Test; -import org.sonar.api.config.Configuration; -import org.sonar.api.config.internal.MapSettings; -import org.sonar.db.DbTester; -import org.sonar.db.component.ComponentDto; -import org.sonar.server.computation.task.projectanalysis.analysis.Branch; -import org.sonar.server.computation.task.projectanalysis.component.DefaultBranchImpl; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.sonar.db.property.PropertyTesting.newComponentPropertyDto; - -public class ProjectConfigurationFactoryTest { - - private static final String PROJECT_KEY = "PROJECT_KEY"; - - @Rule - public DbTester db = DbTester.create(); - - private MapSettings settings = new MapSettings(); - - private ProjectConfigurationFactory underTest = new ProjectConfigurationFactory(settings, db.getDbClient()); - - @Test - public void return_global_settings() { - settings.setProperty("key", "value"); - Configuration config = underTest.newProjectConfiguration(PROJECT_KEY, new DefaultBranchImpl()); - - assertThat(config.get("key")).hasValue("value"); - } - - @Test - public void return_project_settings() { - ComponentDto project = db.components().insertPrivateProject(); - db.properties().insertProperties( - newComponentPropertyDto(project).setKey("1").setValue("val1"), - newComponentPropertyDto(project).setKey("2").setValue("val2"), - newComponentPropertyDto(project).setKey("3").setValue("val3")); - - Configuration config = underTest.newProjectConfiguration(project.getDbKey(), new DefaultBranchImpl()); - - assertThat(config.get("1")).hasValue("val1"); - assertThat(config.get("2")).hasValue("val2"); - assertThat(config.get("3")).hasValue("val3"); - } - - @Test - public void project_settings_override_global_settings() { - settings.setProperty("key", "value"); - ComponentDto project = db.components().insertPrivateProject(); - db.properties().insertProperties(newComponentPropertyDto(project).setKey("key").setValue("value2")); - - Configuration projectConfig = underTest.newProjectConfiguration(project.getDbKey(), new DefaultBranchImpl()); - - assertThat(projectConfig.get("key")).hasValue("value2"); - } - - @Test - public void branch_settings() { - ComponentDto project = db.components().insertMainBranch(); - ComponentDto branch = db.components().insertProjectBranch(project); - db.properties().insertProperties(newComponentPropertyDto(branch).setKey("sonar.leak.period").setValue("1")); - - Configuration config = underTest.newProjectConfiguration(project.getKey(), createBranch(branch.getBranch(), false)); - - assertThat(config.get("sonar.leak.period")).hasValue("1"); - } - - @Test - public void branch_settings_contains_global_settings() { - settings.setProperty("global", "global_value"); - ComponentDto project = db.components().insertMainBranch(); - ComponentDto branch = db.components().insertProjectBranch(project); - db.properties().insertProperties(newComponentPropertyDto(branch).setKey("sonar.leak.period").setValue("1")); - - Configuration config = underTest.newProjectConfiguration(project.getKey(), createBranch(branch.getBranch(), false)); - - assertThat(config.get("global")).hasValue("global_value"); - assertThat(config.get("sonar.leak.period")).hasValue("1"); - } - - @Test - public void branch_settings_contains_project_settings() { - ComponentDto project = db.components().insertMainBranch(); - db.properties().insertProperties(newComponentPropertyDto(project).setKey("key").setValue("value")); - ComponentDto branch = db.components().insertProjectBranch(project); - db.properties().insertProperties(newComponentPropertyDto(branch).setKey("sonar.leak.period").setValue("1")); - - Configuration config = underTest.newProjectConfiguration(project.getKey(), createBranch(branch.getBranch(), false)); - - assertThat(config.get("key")).hasValue("value"); - assertThat(config.get("sonar.leak.period")).hasValue("1"); - } - - @Test - public void branch_settings_override_project_settings() { - ComponentDto project = db.components().insertMainBranch(); - db.properties().insertProperties(newComponentPropertyDto(project).setKey("sonar.leak.period").setValue("1")); - ComponentDto branch = db.components().insertProjectBranch(project); - db.properties().insertProperties(newComponentPropertyDto(branch).setKey("sonar.leak.period").setValue("2")); - - Configuration config = underTest.newProjectConfiguration(project.getKey(), createBranch(branch.getBranch(), false)); - - assertThat(config.get("sonar.leak.period")).hasValue("2"); - } - - @Test - public void main_branch() { - ComponentDto project = db.components().insertMainBranch(); - db.properties().insertProperties(newComponentPropertyDto(project).setKey("sonar.leak.period").setValue("1")); - Branch branch = createBranch("master", true); - when(branch.isMain()).thenReturn(true); - - Configuration config = underTest.newProjectConfiguration(project.getKey(), createBranch(branch.getName(), true)); - - assertThat(config.get("sonar.leak.period")).hasValue("1"); - } - - @Test - public void legacy_branch() { - ComponentDto project = db.components().insertMainBranch(); - db.properties().insertProperties(newComponentPropertyDto(project).setKey("sonar.leak.period").setValue("1")); - Branch branch = createBranch("legacy", true); - when(branch.isLegacyFeature()).thenReturn(true); - - Configuration config = underTest.newProjectConfiguration(project.getKey(), createBranch(branch.getName(), true)); - - assertThat(config.get("sonar.leak.period")).hasValue("1"); - } - - private static Branch createBranch(String name, boolean isMain) { - Branch branch = mock(Branch.class); - when(branch.getName()).thenReturn(name); - when(branch.isMain()).thenReturn(isMain); - return branch; - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/badge/ws/MeasureActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/badge/ws/MeasureActionTest.java index 31c2d4e277d..b45408a3604 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/badge/ws/MeasureActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/badge/ws/MeasureActionTest.java @@ -44,7 +44,7 @@ import org.sonar.db.organization.OrganizationDto; import org.sonar.db.user.UserDto; import org.sonar.server.badge.ws.SvgGenerator.Color; import org.sonar.server.component.ComponentFinder; -import org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating; +import org.sonar.server.measure.Rating; import org.sonar.server.tester.UserSessionRule; import org.sonar.server.ws.TestResponse; import org.sonar.server.ws.WsActionTester; diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ws/ProjectMeasuresQueryFactoryTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ws/ProjectMeasuresQueryFactoryTest.java index a96461d7531..8838ddfc864 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/component/ws/ProjectMeasuresQueryFactoryTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/component/ws/ProjectMeasuresQueryFactoryTest.java @@ -42,7 +42,6 @@ import static org.sonar.server.component.ws.FilterParser.Operator.IN; import static org.sonar.server.component.ws.FilterParser.Operator.LT; import static org.sonar.server.component.ws.FilterParser.Operator.LTE; import static org.sonar.server.component.ws.ProjectMeasuresQueryFactory.newProjectMeasuresQuery; -import static org.sonar.server.computation.task.projectanalysis.measure.Measure.Level.OK; public class ProjectMeasuresQueryFactoryTest { @@ -98,7 +97,7 @@ public class ProjectMeasuresQueryFactoryTest { ProjectMeasuresQuery query = newProjectMeasuresQuery(singletonList(Criterion.builder().setKey("alert_status").setOperator(EQ).setValue("OK").build()), emptySet()); - assertThat(query.getQualityGateStatus().get().name()).isEqualTo(OK.name()); + assertThat(query.getQualityGateStatus().get().name()).isEqualTo("OK"); } @Test diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchProjectsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchProjectsActionTest.java index 4f753a407ad..a91189f110c 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchProjectsActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchProjectsActionTest.java @@ -83,9 +83,6 @@ import static org.sonar.api.server.ws.WebService.Param.PAGE_SIZE; import static org.sonar.api.server.ws.WebService.Param.SORT; import static org.sonar.api.utils.DateUtils.formatDateTime; import static org.sonar.core.util.stream.MoreCollectors.toList; -import static org.sonar.server.computation.task.projectanalysis.metric.Metric.MetricType.DATA; -import static org.sonar.server.computation.task.projectanalysis.metric.Metric.MetricType.PERCENT; -import static org.sonar.server.computation.task.projectanalysis.metric.Metric.MetricType.RATING; import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001; import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_002; import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_003; @@ -199,7 +196,7 @@ public class SearchProjectsActionTest { OrganizationDto organization1Dto = db.organizations().insert(dto -> dto.setKey("my-org-key-1").setName("Foo")); OrganizationDto organization2Dto = db.organizations().insert(dto -> dto.setKey("my-org-key-2").setName("Bar")); - MetricDto coverage = db.measures().insertMetric(c -> c.setKey(COVERAGE).setValueType(PERCENT.name())); + MetricDto coverage = db.measures().insertMetric(c -> c.setKey(COVERAGE).setValueType("PERCENT")); ComponentDto project1 = insertProject(organization1Dto, c -> c .setDbKey(KEY_PROJECT_EXAMPLE_001) .setName("My Project 1") @@ -302,7 +299,7 @@ public class SearchProjectsActionTest { userSession.logIn(); OrganizationDto organization1 = db.organizations().insert(); OrganizationDto organization2 = db.organizations().insert(); - MetricDto coverage = db.measures().insertMetric(c -> c.setKey(COVERAGE).setValueType(PERCENT.name())); + MetricDto coverage = db.measures().insertMetric(c -> c.setKey(COVERAGE).setValueType("PERCENT")); MetricDto ncloc = db.measures().insertMetric(c -> c.setKey(NCLOC).setValueType(INT.name())); ComponentDto project1 = insertProject(organization1, new Measure(coverage, c -> c.setValue(81d)), new Measure(ncloc, c -> c.setValue(10_000d))); ComponentDto project2 = insertProject(organization1, new Measure(coverage, c -> c.setValue(80d)), new Measure(ncloc, c -> c.setValue(10_000d))); @@ -339,7 +336,7 @@ public class SearchProjectsActionTest { public void filter_projects_by_languages() { userSession.logIn(); OrganizationDto organizationDto = db.organizations().insert(); - MetricDto languagesDistribution = db.measures().insertMetric(c -> c.setKey(NCLOC_LANGUAGE_DISTRIBUTION_KEY).setValueType(DATA.name())); + MetricDto languagesDistribution = db.measures().insertMetric(c -> c.setKey(NCLOC_LANGUAGE_DISTRIBUTION_KEY).setValueType("DATA")); ComponentDto project1 = insertProject(organizationDto, new Measure(languagesDistribution, c -> c.setValue(null).setData("=2;java=6;xoo=18"))); ComponentDto project2 = insertProject(organizationDto, new Measure(languagesDistribution, c -> c.setValue(null).setData("java=3;xoo=9"))); ComponentDto project3 = insertProject(organizationDto, new Measure(languagesDistribution, c -> c.setValue(null).setData("xoo=1"))); @@ -397,7 +394,7 @@ public class SearchProjectsActionTest { public void filter_projects_by_coverage() { userSession.logIn(); OrganizationDto organizationDto = db.organizations().insert(); - MetricDto coverage = db.measures().insertMetric(c -> c.setKey(COVERAGE).setValueType(PERCENT.name())); + MetricDto coverage = db.measures().insertMetric(c -> c.setKey(COVERAGE).setValueType("PERCENT")); ComponentDto project1 = insertProject(organizationDto, new Measure(coverage, c -> c.setValue(80d))); ComponentDto project2 = insertProject(organizationDto, new Measure(coverage, c -> c.setValue(85d))); ComponentDto project3 = insertProject(organizationDto, new Measure(coverage, c -> c.setValue(10d))); @@ -411,7 +408,7 @@ public class SearchProjectsActionTest { public void filter_projects_by_new_coverage() { userSession.logIn(); OrganizationDto organizationDto = db.organizations().insert(); - MetricDto coverage = db.measures().insertMetric(c -> c.setKey(NEW_COVERAGE).setValueType(PERCENT.name())); + MetricDto coverage = db.measures().insertMetric(c -> c.setKey(NEW_COVERAGE).setValueType("PERCENT")); ComponentDto project1 = insertProject(organizationDto, new Measure(coverage, c -> c.setVariation(80d))); ComponentDto project2 = insertProject(organizationDto, new Measure(coverage, c -> c.setVariation(85d))); ComponentDto project3 = insertProject(organizationDto, new Measure(coverage, c -> c.setVariation(10d))); @@ -425,7 +422,7 @@ public class SearchProjectsActionTest { public void filter_projects_by_duplications() { userSession.logIn(); OrganizationDto organizationDto = db.organizations().insert(); - MetricDto duplications = db.measures().insertMetric(c -> c.setKey(DUPLICATED_LINES_DENSITY_KEY).setValueType(PERCENT.name())); + MetricDto duplications = db.measures().insertMetric(c -> c.setKey(DUPLICATED_LINES_DENSITY_KEY).setValueType("PERCENT")); ComponentDto project1 = insertProject(organizationDto, new Measure(duplications, c -> c.setValue(80d))); ComponentDto project2 = insertProject(organizationDto, new Measure(duplications, c -> c.setValue(85d))); ComponentDto project3 = insertProject(organizationDto, new Measure(duplications, c -> c.setValue(10d))); @@ -439,8 +436,8 @@ public class SearchProjectsActionTest { public void filter_projects_by_no_duplication() { userSession.logIn(); OrganizationDto organizationDto = db.organizations().insert(); - MetricDto coverage = db.measures().insertMetric(c -> c.setKey(COVERAGE).setValueType(PERCENT.name())); - MetricDto duplications = db.measures().insertMetric(c -> c.setKey(DUPLICATED_LINES_DENSITY_KEY).setValueType(PERCENT.name())); + MetricDto coverage = db.measures().insertMetric(c -> c.setKey(COVERAGE).setValueType("PERCENT")); + MetricDto duplications = db.measures().insertMetric(c -> c.setKey(DUPLICATED_LINES_DENSITY_KEY).setValueType("PERCENT")); ComponentDto project1 = insertProject(organizationDto, new Measure(coverage, c -> c.setValue(10d))); ComponentDto project2 = insertProject(organizationDto, new Measure(duplications, c -> c.setValue(0d))); ComponentDto project3 = insertProject(organizationDto, new Measure(duplications, c -> c.setValue(79d))); @@ -454,8 +451,8 @@ public class SearchProjectsActionTest { public void filter_projects_by_no_duplication_should_not_return_projects_with_duplication() { userSession.logIn(); OrganizationDto organizationDto = db.organizations().insert(); - MetricDto coverage = db.measures().insertMetric(c -> c.setKey(COVERAGE).setValueType(PERCENT.name())); - MetricDto duplications = db.measures().insertMetric(c -> c.setKey(DUPLICATED_LINES_DENSITY_KEY).setValueType(PERCENT.name())); + MetricDto coverage = db.measures().insertMetric(c -> c.setKey(COVERAGE).setValueType("PERCENT")); + MetricDto duplications = db.measures().insertMetric(c -> c.setKey(DUPLICATED_LINES_DENSITY_KEY).setValueType("PERCENT")); insertProject(organizationDto, new Measure(duplications, c -> c.setValue(10d)), new Measure(coverage, c -> c.setValue(50d))); SearchProjectsWsResponse result = call(request.setFilter("duplicated_lines_density = NO_DATA")); @@ -467,7 +464,7 @@ public class SearchProjectsActionTest { public void filter_projects_by_new_duplications() { userSession.logIn(); OrganizationDto organizationDto = db.organizations().insert(); - MetricDto newDuplications = db.measures().insertMetric(c -> c.setKey(NEW_DUPLICATED_LINES_DENSITY_KEY).setValueType(PERCENT.name())); + MetricDto newDuplications = db.measures().insertMetric(c -> c.setKey(NEW_DUPLICATED_LINES_DENSITY_KEY).setValueType("PERCENT")); ComponentDto project1 = insertProject(organizationDto, new Measure(newDuplications, c -> c.setVariation(80d))); ComponentDto project2 = insertProject(organizationDto, new Measure(newDuplications, c -> c.setVariation(85d))); ComponentDto project3 = insertProject(organizationDto, new Measure(newDuplications, c -> c.setVariation(10d))); @@ -635,7 +632,7 @@ public class SearchProjectsActionTest { public void return_languages_facet() { userSession.logIn(); OrganizationDto organizationDto = db.organizations().insert(); - MetricDto languagesDistribution = db.measures().insertMetric(c -> c.setKey(NCLOC_LANGUAGE_DISTRIBUTION_KEY).setValueType(DATA.name())); + MetricDto languagesDistribution = db.measures().insertMetric(c -> c.setKey(NCLOC_LANGUAGE_DISTRIBUTION_KEY).setValueType("DATA")); insertProject(organizationDto, new Measure(languagesDistribution, c -> c.setValue(null).setData("=2;java=6;xoo=18"))); insertProject(organizationDto, new Measure(languagesDistribution, c -> c.setValue(null).setData("java=5;xoo=19"))); insertProject(organizationDto, new Measure(languagesDistribution, c -> c.setValue(null).setData("xoo=1"))); @@ -658,7 +655,7 @@ public class SearchProjectsActionTest { public void return_languages_facet_with_language_having_no_project_if_language_is_in_filter() { userSession.logIn(); OrganizationDto organizationDto = db.organizations().insert(); - MetricDto languagesDistribution = db.measures().insertMetric(c -> c.setKey(NCLOC_LANGUAGE_DISTRIBUTION_KEY).setValueType(DATA.name())); + MetricDto languagesDistribution = db.measures().insertMetric(c -> c.setKey(NCLOC_LANGUAGE_DISTRIBUTION_KEY).setValueType("DATA")); insertProject(organizationDto, new Measure(languagesDistribution, c -> c.setValue(null).setData("=2;java=6"))); insertProject(organizationDto, new Measure(languagesDistribution, c -> c.setValue(null).setData("java=5"))); @@ -723,7 +720,7 @@ public class SearchProjectsActionTest { public void return_rating_facet(String ratingMetricKey) { userSession.logIn(); OrganizationDto organization = db.organizations().insert(); - MetricDto ratingMetric = db.measures().insertMetric(c -> c.setKey(ratingMetricKey).setValueType(RATING.name())); + MetricDto ratingMetric = db.measures().insertMetric(c -> c.setKey(ratingMetricKey).setValueType("RATING")); insertProject(organization, new Measure(ratingMetric, c -> c.setValue(1d))); insertProject(organization, new Measure(ratingMetric, c -> c.setValue(1d))); insertProject(organization, new Measure(ratingMetric, c -> c.setValue(3d))); @@ -749,7 +746,7 @@ public class SearchProjectsActionTest { public void return_new_rating_facet(String newRatingMetricKey) { userSession.logIn(); OrganizationDto organization = db.organizations().insert(); - MetricDto newRatingMetric = db.measures().insertMetric(c -> c.setKey(newRatingMetricKey).setValueType(RATING.name())); + MetricDto newRatingMetric = db.measures().insertMetric(c -> c.setKey(newRatingMetricKey).setValueType("RATING")); insertProject(organization, new Measure(newRatingMetric, c -> c.setVariation(1d))); insertProject(organization, new Measure(newRatingMetric, c -> c.setVariation(1d))); insertProject(organization, new Measure(newRatingMetric, c -> c.setVariation(3d))); @@ -774,7 +771,7 @@ public class SearchProjectsActionTest { public void return_coverage_facet() { userSession.logIn(); OrganizationDto organizationDto = db.organizations().insert(); - MetricDto coverage = db.measures().insertMetric(c -> c.setKey(COVERAGE).setValueType(PERCENT.name())); + MetricDto coverage = db.measures().insertMetric(c -> c.setKey(COVERAGE).setValueType("PERCENT")); insertProject(organizationDto); insertProject(organizationDto, new Measure(coverage, c -> c.setValue(80d))); insertProject(organizationDto, new Measure(coverage, c -> c.setValue(85d))); @@ -800,7 +797,7 @@ public class SearchProjectsActionTest { public void return_new_coverage_facet() { userSession.logIn(); OrganizationDto organizationDto = db.organizations().insert(); - MetricDto coverage = db.measures().insertMetric(c -> c.setKey(NEW_COVERAGE).setValueType(PERCENT.name())); + MetricDto coverage = db.measures().insertMetric(c -> c.setKey(NEW_COVERAGE).setValueType("PERCENT")); insertProject(organizationDto); insertProject(organizationDto, new Measure(coverage, c -> c.setVariation(80d))); insertProject(organizationDto, new Measure(coverage, c -> c.setVariation(85d))); @@ -826,7 +823,7 @@ public class SearchProjectsActionTest { public void return_duplications_facet() { userSession.logIn(); OrganizationDto organizationDto = db.organizations().insert(); - MetricDto coverage = db.measures().insertMetric(c -> c.setKey(DUPLICATED_LINES_DENSITY_KEY).setValueType(PERCENT.name())); + MetricDto coverage = db.measures().insertMetric(c -> c.setKey(DUPLICATED_LINES_DENSITY_KEY).setValueType("PERCENT")); insertProject(organizationDto, new Measure(coverage, c -> c.setValue(10d))); insertProject(organizationDto, new Measure(coverage, c -> c.setValue(15d))); insertProject(organizationDto, new Measure(coverage, c -> c.setValue(5d))); @@ -852,7 +849,7 @@ public class SearchProjectsActionTest { public void return_new_duplications_facet() { userSession.logIn(); OrganizationDto organizationDto = db.organizations().insert(); - MetricDto coverage = db.measures().insertMetric(c -> c.setKey(NEW_DUPLICATED_LINES_DENSITY_KEY).setValueType(PERCENT.name())); + MetricDto coverage = db.measures().insertMetric(c -> c.setKey(NEW_DUPLICATED_LINES_DENSITY_KEY).setValueType("PERCENT")); insertProject(organizationDto); insertProject(organizationDto, new Measure(coverage, c -> c.setVariation(10d))); insertProject(organizationDto, new Measure(coverage, c -> c.setVariation(15d))); diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/analysis/ProjectConfigurationFactoryTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/analysis/ProjectConfigurationFactoryTest.java new file mode 100644 index 00000000000..a03901e726a --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/analysis/ProjectConfigurationFactoryTest.java @@ -0,0 +1,159 @@ +/* + * 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.computation.task.projectanalysis.analysis; + +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.config.Configuration; +import org.sonar.api.config.internal.MapSettings; +import org.sonar.db.DbTester; +import org.sonar.db.component.ComponentDto; +import org.sonar.server.computation.task.projectanalysis.component.DefaultBranchImpl; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.sonar.db.property.PropertyTesting.newComponentPropertyDto; + +public class ProjectConfigurationFactoryTest { + + private static final String PROJECT_KEY = "PROJECT_KEY"; + + @Rule + public DbTester db = DbTester.create(); + + private MapSettings settings = new MapSettings(); + + private ProjectConfigurationFactory underTest = new ProjectConfigurationFactory(settings, db.getDbClient()); + + @Test + public void return_global_settings() { + settings.setProperty("key", "value"); + Configuration config = underTest.newProjectConfiguration(PROJECT_KEY, new DefaultBranchImpl()); + + assertThat(config.get("key")).hasValue("value"); + } + + @Test + public void return_project_settings() { + ComponentDto project = db.components().insertPrivateProject(); + db.properties().insertProperties( + newComponentPropertyDto(project).setKey("1").setValue("val1"), + newComponentPropertyDto(project).setKey("2").setValue("val2"), + newComponentPropertyDto(project).setKey("3").setValue("val3")); + + Configuration config = underTest.newProjectConfiguration(project.getDbKey(), new DefaultBranchImpl()); + + assertThat(config.get("1")).hasValue("val1"); + assertThat(config.get("2")).hasValue("val2"); + assertThat(config.get("3")).hasValue("val3"); + } + + @Test + public void project_settings_override_global_settings() { + settings.setProperty("key", "value"); + ComponentDto project = db.components().insertPrivateProject(); + db.properties().insertProperties(newComponentPropertyDto(project).setKey("key").setValue("value2")); + + Configuration projectConfig = underTest.newProjectConfiguration(project.getDbKey(), new DefaultBranchImpl()); + + assertThat(projectConfig.get("key")).hasValue("value2"); + } + + @Test + public void branch_settings() { + ComponentDto project = db.components().insertMainBranch(); + ComponentDto branch = db.components().insertProjectBranch(project); + db.properties().insertProperties(newComponentPropertyDto(branch).setKey("sonar.leak.period").setValue("1")); + + Configuration config = underTest.newProjectConfiguration(project.getKey(), createBranch(branch.getBranch(), false)); + + assertThat(config.get("sonar.leak.period")).hasValue("1"); + } + + @Test + public void branch_settings_contains_global_settings() { + settings.setProperty("global", "global_value"); + ComponentDto project = db.components().insertMainBranch(); + ComponentDto branch = db.components().insertProjectBranch(project); + db.properties().insertProperties(newComponentPropertyDto(branch).setKey("sonar.leak.period").setValue("1")); + + Configuration config = underTest.newProjectConfiguration(project.getKey(), createBranch(branch.getBranch(), false)); + + assertThat(config.get("global")).hasValue("global_value"); + assertThat(config.get("sonar.leak.period")).hasValue("1"); + } + + @Test + public void branch_settings_contains_project_settings() { + ComponentDto project = db.components().insertMainBranch(); + db.properties().insertProperties(newComponentPropertyDto(project).setKey("key").setValue("value")); + ComponentDto branch = db.components().insertProjectBranch(project); + db.properties().insertProperties(newComponentPropertyDto(branch).setKey("sonar.leak.period").setValue("1")); + + Configuration config = underTest.newProjectConfiguration(project.getKey(), createBranch(branch.getBranch(), false)); + + assertThat(config.get("key")).hasValue("value"); + assertThat(config.get("sonar.leak.period")).hasValue("1"); + } + + @Test + public void branch_settings_override_project_settings() { + ComponentDto project = db.components().insertMainBranch(); + db.properties().insertProperties(newComponentPropertyDto(project).setKey("sonar.leak.period").setValue("1")); + ComponentDto branch = db.components().insertProjectBranch(project); + db.properties().insertProperties(newComponentPropertyDto(branch).setKey("sonar.leak.period").setValue("2")); + + Configuration config = underTest.newProjectConfiguration(project.getKey(), createBranch(branch.getBranch(), false)); + + assertThat(config.get("sonar.leak.period")).hasValue("2"); + } + + @Test + public void main_branch() { + ComponentDto project = db.components().insertMainBranch(); + db.properties().insertProperties(newComponentPropertyDto(project).setKey("sonar.leak.period").setValue("1")); + Branch branch = createBranch("master", true); + when(branch.isMain()).thenReturn(true); + + Configuration config = underTest.newProjectConfiguration(project.getKey(), createBranch(branch.getName(), true)); + + assertThat(config.get("sonar.leak.period")).hasValue("1"); + } + + @Test + public void legacy_branch() { + ComponentDto project = db.components().insertMainBranch(); + db.properties().insertProperties(newComponentPropertyDto(project).setKey("sonar.leak.period").setValue("1")); + Branch branch = createBranch("legacy", true); + when(branch.isLegacyFeature()).thenReturn(true); + + Configuration config = underTest.newProjectConfiguration(project.getKey(), createBranch(branch.getName(), true)); + + assertThat(config.get("sonar.leak.period")).hasValue("1"); + } + + private static Branch createBranch(String name, boolean isMain) { + Branch branch = mock(Branch.class); + when(branch.getName()).thenReturn(name); + when(branch.isMain()).thenReturn(isMain); + return branch; + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/component/ConfigurationRepositoryTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/component/ConfigurationRepositoryTest.java index 810e19c0fab..7255a761b39 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/component/ConfigurationRepositoryTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/component/ConfigurationRepositoryTest.java @@ -25,7 +25,7 @@ import org.junit.Test; import org.sonar.api.config.Configuration; import org.sonar.api.config.internal.MapSettings; import org.sonar.api.utils.System2; -import org.sonar.ce.settings.ProjectConfigurationFactory; +import org.sonar.server.computation.task.projectanalysis.analysis.ProjectConfigurationFactory; import org.sonar.db.DbClient; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/formula/counter/RatingValueTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/formula/counter/RatingValueTest.java index 742bb1d35e9..fc4a30459f1 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/formula/counter/RatingValueTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/formula/counter/RatingValueTest.java @@ -20,13 +20,13 @@ package org.sonar.server.computation.task.projectanalysis.formula.counter; import org.junit.Test; -import org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating; +import org.sonar.server.measure.Rating; import static org.assertj.core.api.Assertions.assertThat; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.A; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.B; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.C; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.D; +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; public class RatingValueTest { diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/NewExternalRuleTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/NewExternalRuleTest.java deleted file mode 100644 index 16ee04142b7..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/NewExternalRuleTest.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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.computation.task.projectanalysis.issue; - -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.rule.RuleKey; - -import static org.assertj.core.api.Assertions.assertThat; - -public class NewExternalRuleTest { - @org.junit.Rule - public ExpectedException exception = ExpectedException.none(); - - @Test - public void should_build_new_external_rule() { - NewExternalRule.Builder builder = new NewExternalRule.Builder() - .setKey(RuleKey.of("repo", "rule")) - .setPluginKey("repo") - .setName("name"); - - assertThat(builder.name()).isEqualTo("name"); - - NewExternalRule rule = builder.build(); - - assertThat(rule.getName()).isEqualTo("name"); - assertThat(rule.getPluginKey()).isEqualTo("repo"); - } - - @Test - public void fail_if_rule_key_is_not_set() { - exception.expect(NullPointerException.class); - exception.expectMessage("'key' not expected to be null for an external rule"); - - new NewExternalRule.Builder() - .build(); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/RuleRepositoryImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/RuleRepositoryImplTest.java index 910cd12458b..9cffff2f8f0 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/RuleRepositoryImplTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/RuleRepositoryImplTest.java @@ -38,6 +38,7 @@ import org.sonar.db.rule.RuleDefinitionDto; import org.sonar.db.rule.RuleDto; import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolderRule; import org.sonar.server.rule.ExternalRuleCreator; +import org.sonar.server.rule.NewExternalRule; import org.sonar.server.rule.index.RuleIndexer; import static org.assertj.core.api.Assertions.assertThat; diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/RuleRepositoryRule.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/RuleRepositoryRule.java index 57300aca811..92ec30c8ebe 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/RuleRepositoryRule.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/RuleRepositoryRule.java @@ -27,6 +27,7 @@ import java.util.function.Supplier; import org.junit.rules.ExternalResource; import org.sonar.api.rule.RuleKey; import org.sonar.db.DbSession; +import org.sonar.server.rule.NewExternalRule; import static com.google.common.base.Preconditions.checkArgument; import static java.util.Objects.requireNonNull; diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/measure/BestValueOptimizationTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/measure/BestValueOptimizationTest.java index e023123bc95..0814849dd52 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/measure/BestValueOptimizationTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/measure/BestValueOptimizationTest.java @@ -28,8 +28,8 @@ import org.sonar.server.computation.task.projectanalysis.metric.MetricImpl; import static org.assertj.core.api.Assertions.assertThat; import static org.sonar.server.computation.task.projectanalysis.measure.Measure.newMeasureBuilder; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.A; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.B; +import static org.sonar.server.measure.Rating.A; +import static org.sonar.server.measure.Rating.B; public class BestValueOptimizationTest { diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/measure/PostMeasuresComputationChecksStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/measure/PostMeasuresComputationChecksStepTest.java new file mode 100644 index 00000000000..f9a3579a980 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/measure/PostMeasuresComputationChecksStepTest.java @@ -0,0 +1,139 @@ +/* + * 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.computation.task.projectanalysis.measure; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.mockito.ArgumentCaptor; +import org.mockito.InOrder; +import org.sonar.api.measures.CoreMetrics; +import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolderRule; +import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule; +import org.sonar.server.computation.task.projectanalysis.measure.PostMeasuresComputationCheck.Context; +import org.sonar.server.computation.task.projectanalysis.metric.MetricRepositoryRule; +import org.sonar.server.project.Project; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.fail; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.sonar.api.measures.CoreMetrics.NCLOC; +import static org.sonar.server.computation.task.projectanalysis.component.ReportComponent.DUMB_PROJECT; + +public class PostMeasuresComputationChecksStepTest { + + @Rule + public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule().setRoot(DUMB_PROJECT); + @Rule + public MetricRepositoryRule metricRepository = new MetricRepositoryRule().add(NCLOC); + @Rule + public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository); + @Rule + public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule(); + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Test + public void execute_extensions() { + PostMeasuresComputationCheck check1 = mock(PostMeasuresComputationCheck.class); + PostMeasuresComputationCheck check2 = mock(PostMeasuresComputationCheck.class); + + newStep(check1, check2).execute(); + + InOrder inOrder = inOrder(check1, check2); + inOrder.verify(check1).onCheck(any(Context.class)); + inOrder.verify(check2).onCheck(any(Context.class)); + } + + @Test + public void context_contains_project_uuid_from_analysis_metada_holder() { + analysisMetadataHolder.setProject(new Project("project_uuid", "project_key", "project_name")); + PostMeasuresComputationCheck check = mock(PostMeasuresComputationCheck.class); + + newStep(check).execute(); + + ArgumentCaptor contextArgumentCaptor = ArgumentCaptor.forClass(Context.class); + verify(check).onCheck(contextArgumentCaptor.capture()); + assertThat(contextArgumentCaptor.getValue().getProjectUuid()).isEqualTo("project_uuid"); + } + + @Test + public void context_contains_ncloc_when_available() { + PostMeasuresComputationCheck check = mock(PostMeasuresComputationCheck.class); + measureRepository.addRawMeasure(DUMB_PROJECT.getReportAttributes().getRef(), CoreMetrics.NCLOC_KEY, Measure.newMeasureBuilder().create(10)); + + newStep(check).execute(); + + ArgumentCaptor contextArgumentCaptor = ArgumentCaptor.forClass(Context.class); + verify(check).onCheck(contextArgumentCaptor.capture()); + assertThat(contextArgumentCaptor.getValue().getNcloc()).isEqualTo(10); + } + + @Test + public void ncloc_is_zero_in_context_when_not_available() { + PostMeasuresComputationCheck check = mock(PostMeasuresComputationCheck.class); + + newStep(check).execute(); + + ArgumentCaptor contextArgumentCaptor = ArgumentCaptor.forClass(Context.class); + verify(check).onCheck(contextArgumentCaptor.capture()); + assertThat(contextArgumentCaptor.getValue().getNcloc()).isEqualTo(0); + } + + @Test + public void do_nothing_if_no_extensions() { + // no failure + newStep().execute(); + } + + @Test + public void fail_if_an_extension_throws_an_exception() { + PostMeasuresComputationCheck check1 = mock(PostMeasuresComputationCheck.class); + PostMeasuresComputationCheck check2 = mock(PostMeasuresComputationCheck.class); + doThrow(new IllegalStateException("BOOM")).when(check2).onCheck(any(Context.class)); + PostMeasuresComputationCheck check3 = mock(PostMeasuresComputationCheck.class); + + try { + newStep(check1, check2, check3).execute(); + fail(); + } catch (IllegalStateException e) { + assertThat(e).hasMessage("BOOM"); + verify(check1).onCheck(any(Context.class)); + verify(check3, never()).onCheck(any(Context.class)); + } + } + + @Test + public void test_getDescription() { + assertThat(newStep().getDescription()).isNotEmpty(); + } + + private PostMeasuresComputationChecksStep newStep(PostMeasuresComputationCheck... postMeasuresComputationChecks) { + if (postMeasuresComputationChecks.length == 0){ + return new PostMeasuresComputationChecksStep(treeRootHolder, metricRepository, measureRepository, analysisMetadataHolder); + } + return new PostMeasuresComputationChecksStep(treeRootHolder, metricRepository, measureRepository, analysisMetadataHolder, postMeasuresComputationChecks); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/DebtRatingGridTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/DebtRatingGridTest.java deleted file mode 100644 index 8f5b2e7ad12..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/DebtRatingGridTest.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * 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.computation.task.projectanalysis.qualitymodel; - -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.computation.task.projectanalysis.qualitymodel.Rating.A; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.B; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.C; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.D; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.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/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitorTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitorTest.java index f5ee683bf3b..261c257de2c 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitorTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/MaintainabilityMeasuresVisitorTest.java @@ -31,6 +31,8 @@ import org.sonar.server.computation.task.projectanalysis.issue.ComponentIssuesRe import org.sonar.server.computation.task.projectanalysis.measure.Measure; import org.sonar.server.computation.task.projectanalysis.measure.MeasureRepositoryRule; import org.sonar.server.computation.task.projectanalysis.metric.MetricRepositoryRule; +import org.sonar.server.measure.DebtRatingGrid; +import org.sonar.server.measure.Rating; import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; @@ -56,9 +58,9 @@ import static org.sonar.server.computation.task.projectanalysis.component.Report import static org.sonar.server.computation.task.projectanalysis.measure.Measure.newMeasureBuilder; import static org.sonar.server.computation.task.projectanalysis.measure.MeasureRepoEntry.entryOf; import static org.sonar.server.computation.task.projectanalysis.measure.MeasureRepoEntry.toEntries; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.A; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.C; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.E; +import static org.sonar.server.measure.Rating.A; +import static org.sonar.server.measure.Rating.C; +import static org.sonar.server.measure.Rating.E; public class MaintainabilityMeasuresVisitorTest { diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/NewMaintainabilityMeasuresVisitorTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/NewMaintainabilityMeasuresVisitorTest.java index c9564da5bd0..85c0c128655 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/NewMaintainabilityMeasuresVisitorTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/NewMaintainabilityMeasuresVisitorTest.java @@ -43,6 +43,8 @@ import org.sonar.server.computation.task.projectanalysis.period.Period; import org.sonar.server.computation.task.projectanalysis.period.PeriodHolderRule; import org.sonar.server.computation.task.projectanalysis.scm.Changeset; import org.sonar.server.computation.task.projectanalysis.scm.ScmInfoRepositoryRule; +import org.sonar.server.measure.DebtRatingGrid; +import org.sonar.server.measure.Rating; import static com.google.common.base.Preconditions.checkArgument; import static org.mockito.Mockito.mock; @@ -63,8 +65,8 @@ import static org.sonar.server.computation.task.projectanalysis.component.Compon import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.PROJECT; import static org.sonar.server.computation.task.projectanalysis.measure.Measure.newMeasureBuilder; import static org.sonar.server.computation.task.projectanalysis.measure.MeasureAssert.assertThat; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.A; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.D; +import static org.sonar.server.measure.Rating.A; +import static org.sonar.server.measure.Rating.D; public class NewMaintainabilityMeasuresVisitorTest { diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/NewReliabilityAndSecurityRatingMeasuresVisitorTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/NewReliabilityAndSecurityRatingMeasuresVisitorTest.java index 34c85fe1e4b..1346d176fcc 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/NewReliabilityAndSecurityRatingMeasuresVisitorTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/NewReliabilityAndSecurityRatingMeasuresVisitorTest.java @@ -39,6 +39,7 @@ import org.sonar.server.computation.task.projectanalysis.measure.MeasureReposito import org.sonar.server.computation.task.projectanalysis.metric.MetricRepositoryRule; import org.sonar.server.computation.task.projectanalysis.period.Period; import org.sonar.server.computation.task.projectanalysis.period.PeriodHolderRule; +import org.sonar.server.measure.Rating; import static org.assertj.core.api.Assertions.assertThat; import static org.sonar.api.issue.Issue.RESOLUTION_FIXED; @@ -60,11 +61,11 @@ import static org.sonar.server.computation.task.projectanalysis.component.Compon import static org.sonar.server.computation.task.projectanalysis.component.Component.Type.PROJECT; import static org.sonar.server.computation.task.projectanalysis.component.ReportComponent.builder; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.A; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.B; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.C; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.D; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.E; +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 NewReliabilityAndSecurityRatingMeasuresVisitorTest { diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitorTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitorTest.java index 9582158a88f..722c37d8532 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitorTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/qualitymodel/ReliabilityAndSecurityRatingMeasuresVisitorTest.java @@ -37,6 +37,7 @@ import org.sonar.server.computation.task.projectanalysis.issue.FillComponentIssu import org.sonar.server.computation.task.projectanalysis.measure.Measure; import org.sonar.server.computation.task.projectanalysis.measure.MeasureRepositoryRule; import org.sonar.server.computation.task.projectanalysis.metric.MetricRepositoryRule; +import org.sonar.server.measure.Rating; import static org.assertj.core.api.Assertions.assertThat; import static org.sonar.api.issue.Issue.RESOLUTION_FIXED; @@ -61,11 +62,11 @@ import static org.sonar.server.computation.task.projectanalysis.measure.Measure. import static org.sonar.server.computation.task.projectanalysis.measure.MeasureRepoEntry.entryOf; import static org.sonar.server.computation.task.projectanalysis.measure.MeasureRepoEntry.toEntries; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.A; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.B; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.C; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.D; -import static org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating.E; +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 ReliabilityAndSecurityRatingMeasuresVisitorTest { diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/PersistExternalRulesStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/PersistExternalRulesStepTest.java index c265a91a82d..aefd8fb0244 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/PersistExternalRulesStepTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/step/PersistExternalRulesStepTest.java @@ -30,7 +30,7 @@ import org.sonar.db.DbTester; import org.sonar.db.rule.RuleDao; import org.sonar.db.rule.RuleDefinitionDto; import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolderRule; -import org.sonar.server.computation.task.projectanalysis.issue.NewExternalRule; +import org.sonar.server.rule.NewExternalRule; import org.sonar.server.computation.task.projectanalysis.issue.RuleRepositoryImpl; import org.sonar.server.computation.task.step.ComputationStep; import org.sonar.server.es.EsTester; diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/step/PostMeasuresComputationChecksStepTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/step/PostMeasuresComputationChecksStepTest.java deleted file mode 100644 index b7bf64abac1..00000000000 --- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/step/PostMeasuresComputationChecksStepTest.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * 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.computation.task.step; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.mockito.ArgumentCaptor; -import org.mockito.InOrder; -import org.sonar.api.measures.CoreMetrics; -import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolderRule; -import org.sonar.server.computation.task.projectanalysis.component.TreeRootHolderRule; -import org.sonar.server.computation.task.projectanalysis.measure.Measure; -import org.sonar.server.computation.task.projectanalysis.measure.MeasureRepositoryRule; -import org.sonar.server.computation.task.projectanalysis.metric.MetricRepositoryRule; -import org.sonar.server.computation.task.step.PostMeasuresComputationCheck.Context; -import org.sonar.server.project.Project; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.sonar.api.measures.CoreMetrics.NCLOC; -import static org.sonar.server.computation.task.projectanalysis.component.ReportComponent.DUMB_PROJECT; - -public class PostMeasuresComputationChecksStepTest { - - @Rule - public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule().setRoot(DUMB_PROJECT); - @Rule - public MetricRepositoryRule metricRepository = new MetricRepositoryRule().add(NCLOC); - @Rule - public MeasureRepositoryRule measureRepository = MeasureRepositoryRule.create(treeRootHolder, metricRepository); - @Rule - public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule(); - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Test - public void execute_extensions() { - PostMeasuresComputationCheck check1 = mock(PostMeasuresComputationCheck.class); - PostMeasuresComputationCheck check2 = mock(PostMeasuresComputationCheck.class); - - newStep(check1, check2).execute(); - - InOrder inOrder = inOrder(check1, check2); - inOrder.verify(check1).onCheck(any(Context.class)); - inOrder.verify(check2).onCheck(any(Context.class)); - } - - @Test - public void context_contains_project_uuid_from_analysis_metada_holder() { - analysisMetadataHolder.setProject(new Project("project_uuid", "project_key", "project_name")); - PostMeasuresComputationCheck check = mock(PostMeasuresComputationCheck.class); - - newStep(check).execute(); - - ArgumentCaptor contextArgumentCaptor = ArgumentCaptor.forClass(Context.class); - verify(check).onCheck(contextArgumentCaptor.capture()); - assertThat(contextArgumentCaptor.getValue().getProjectUuid()).isEqualTo("project_uuid"); - } - - @Test - public void context_contains_ncloc_when_available() { - PostMeasuresComputationCheck check = mock(PostMeasuresComputationCheck.class); - measureRepository.addRawMeasure(DUMB_PROJECT.getReportAttributes().getRef(), CoreMetrics.NCLOC_KEY, Measure.newMeasureBuilder().create(10)); - - newStep(check).execute(); - - ArgumentCaptor contextArgumentCaptor = ArgumentCaptor.forClass(Context.class); - verify(check).onCheck(contextArgumentCaptor.capture()); - assertThat(contextArgumentCaptor.getValue().getNcloc()).isEqualTo(10); - } - - @Test - public void ncloc_is_zero_in_context_when_not_available() { - PostMeasuresComputationCheck check = mock(PostMeasuresComputationCheck.class); - - newStep(check).execute(); - - ArgumentCaptor contextArgumentCaptor = ArgumentCaptor.forClass(Context.class); - verify(check).onCheck(contextArgumentCaptor.capture()); - assertThat(contextArgumentCaptor.getValue().getNcloc()).isEqualTo(0); - } - - @Test - public void do_nothing_if_no_extensions() { - // no failure - newStep().execute(); - } - - @Test - public void fail_if_an_extension_throws_an_exception() { - PostMeasuresComputationCheck check1 = mock(PostMeasuresComputationCheck.class); - PostMeasuresComputationCheck check2 = mock(PostMeasuresComputationCheck.class); - doThrow(new IllegalStateException("BOOM")).when(check2).onCheck(any(Context.class)); - PostMeasuresComputationCheck check3 = mock(PostMeasuresComputationCheck.class); - - try { - newStep(check1, check2, check3).execute(); - fail(); - } catch (IllegalStateException e) { - assertThat(e).hasMessage("BOOM"); - verify(check1).onCheck(any(Context.class)); - verify(check3, never()).onCheck(any(Context.class)); - } - } - - @Test - public void test_getDescription() { - assertThat(newStep().getDescription()).isNotEmpty(); - } - - private PostMeasuresComputationChecksStep newStep(PostMeasuresComputationCheck... postMeasuresComputationChecks) { - if (postMeasuresComputationChecks.length == 0){ - return new PostMeasuresComputationChecksStep(treeRootHolder, metricRepository, measureRepository, analysisMetadataHolder); - } - return new PostMeasuresComputationChecksStep(treeRootHolder, metricRepository, measureRepository, analysisMetadataHolder, postMeasuresComputationChecks); - } -} diff --git a/server/sonar-server/src/test/java/org/sonar/server/measure/DebtRatingGridTest.java b/server/sonar-server/src/test/java/org/sonar/server/measure/DebtRatingGridTest.java new file mode 100644 index 00000000000..0208ae16f02 --- /dev/null +++ b/server/sonar-server/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/src/test/java/org/sonar/server/measure/live/IssueMetricFormulaFactoryImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/measure/live/IssueMetricFormulaFactoryImplTest.java index ca7fb566f65..5de939987ab 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/measure/live/IssueMetricFormulaFactoryImplTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/measure/live/IssueMetricFormulaFactoryImplTest.java @@ -35,8 +35,8 @@ import org.sonar.api.rule.Severity; import org.sonar.api.rules.RuleType; import org.sonar.db.component.ComponentDto; import org.sonar.db.issue.IssueGroupDto; -import org.sonar.server.computation.task.projectanalysis.qualitymodel.DebtRatingGrid; -import org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating; +import org.sonar.server.measure.DebtRatingGrid; +import org.sonar.server.measure.Rating; import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; diff --git a/server/sonar-server/src/test/java/org/sonar/server/measure/live/LiveMeasureComputerImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/measure/live/LiveMeasureComputerImplTest.java index 4aff277f099..d94b12001a7 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/measure/live/LiveMeasureComputerImplTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/measure/live/LiveMeasureComputerImplTest.java @@ -47,7 +47,7 @@ import org.sonar.db.component.ComponentTesting; import org.sonar.db.measure.LiveMeasureDto; import org.sonar.db.metric.MetricDto; import org.sonar.db.organization.OrganizationDto; -import org.sonar.server.computation.task.projectanalysis.qualitymodel.Rating; +import org.sonar.server.measure.Rating; import org.sonar.server.es.ProjectIndexer; import org.sonar.server.es.TestProjectIndexers; import org.sonar.server.qualitygate.EvaluatedQualityGate; diff --git a/server/sonar-server/src/test/java/org/sonar/server/measure/ws/ComponentActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/measure/ws/ComponentActionTest.java index 057002c7ccd..90653292e60 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/measure/ws/ComponentActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/measure/ws/ComponentActionTest.java @@ -33,7 +33,6 @@ import org.sonar.db.measure.LiveMeasureDto; import org.sonar.db.metric.MetricDto; import org.sonar.db.organization.OrganizationDto; import org.sonar.server.component.TestComponentFinder; -import org.sonar.server.computation.task.projectanalysis.measure.Measure; import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; @@ -53,15 +52,14 @@ import static org.sonar.api.web.UserRole.USER; import static org.sonar.db.component.BranchType.PULL_REQUEST; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.db.component.ComponentTesting.newProjectCopy; -import static org.sonar.server.component.ws.MeasuresWsParameters.PARAM_PULL_REQUEST; -import static org.sonar.server.computation.task.projectanalysis.metric.Metric.MetricType.INT; -import static org.sonar.test.JsonAssert.assertJson; import static org.sonar.server.component.ws.MeasuresWsParameters.DEPRECATED_PARAM_COMPONENT_ID; import static org.sonar.server.component.ws.MeasuresWsParameters.PARAM_ADDITIONAL_FIELDS; import static org.sonar.server.component.ws.MeasuresWsParameters.PARAM_BRANCH; import static org.sonar.server.component.ws.MeasuresWsParameters.PARAM_COMPONENT; import static org.sonar.server.component.ws.MeasuresWsParameters.PARAM_DEVELOPER_ID; import static org.sonar.server.component.ws.MeasuresWsParameters.PARAM_METRIC_KEYS; +import static org.sonar.server.component.ws.MeasuresWsParameters.PARAM_PULL_REQUEST; +import static org.sonar.test.JsonAssert.assertJson; public class ComponentActionTest { @@ -95,7 +93,7 @@ public class ComponentActionTest { public void provided_project() { ComponentDto project = db.components().insertPrivateProject(); userSession.addProjectPermission(UserRole.USER, project); - MetricDto metric = db.measures().insertMetric(m -> m.setValueType(INT.name())); + MetricDto metric = db.measures().insertMetric(m -> m.setValueType("INT")); ComponentWsResponse response = newRequest(project.getKey(), metric.getKey()); @@ -109,7 +107,7 @@ public class ComponentActionTest { ComponentDto project = db.components().insertPrivateProject(); userSession.addProjectPermission(UserRole.USER, project); db.components().insertSnapshot(project); - MetricDto metric = db.measures().insertMetric(m -> m.setValueType(INT.name())); + MetricDto metric = db.measures().insertMetric(m -> m.setValueType("INT")); String response = ws.newRequest() .setParam(PARAM_COMPONENT, project.getKey()) @@ -128,7 +126,7 @@ public class ComponentActionTest { ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey("my_branch")); SnapshotDto analysis = db.components().insertSnapshot(branch); ComponentDto file = db.components().insertComponent(newFileDto(branch)); - MetricDto complexity = db.measures().insertMetric(m1 -> m1.setKey("complexity").setValueType(INT.name())); + MetricDto complexity = db.measures().insertMetric(m1 -> m1.setKey("complexity").setValueType("INT")); LiveMeasureDto measure = db.measures().insertLiveMeasure(file, complexity, m -> m.setValue(12.0d).setVariation(2.0d)); ComponentWsResponse response = ws.newRequest() @@ -151,7 +149,7 @@ public class ComponentActionTest { ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey("pr-123").setBranchType(PULL_REQUEST)); SnapshotDto analysis = db.components().insertSnapshot(branch); ComponentDto file = db.components().insertComponent(newFileDto(branch)); - MetricDto complexity = db.measures().insertMetric(m1 -> m1.setKey("complexity").setValueType(INT.name())); + MetricDto complexity = db.measures().insertMetric(m1 -> m1.setKey("complexity").setValueType("INT")); LiveMeasureDto measure = db.measures().insertLiveMeasure(file, complexity, m -> m.setValue(12.0d).setVariation(2.0d)); ComponentWsResponse response = ws.newRequest() @@ -174,7 +172,7 @@ public class ComponentActionTest { ComponentDto view = db.components().insertView(); db.components().insertSnapshot(view); ComponentDto projectCopy = db.components().insertComponent(newProjectCopy("project-uuid-copy", project, view)); - MetricDto metric = db.measures().insertMetric(m -> m.setValueType(INT.name())); + MetricDto metric = db.measures().insertMetric(m -> m.setValueType("INT")); ComponentWsResponse response = newRequest(projectCopy.getKey(), metric.getKey()); @@ -187,7 +185,7 @@ public class ComponentActionTest { ComponentDto project = db.components().insertPrivateProject(); userSession.addProjectPermission(UserRole.USER, project); db.components().insertSnapshot(project); - MetricDto metric = db.measures().insertMetric(m -> m.setValueType(INT.name())); + MetricDto metric = db.measures().insertMetric(m -> m.setValueType("INT")); ComponentWsResponse response = newRequest(project.getKey(), metric.getKey()); @@ -199,7 +197,7 @@ public class ComponentActionTest { ComponentDto project = db.components().insertPrivateProject(); userSession.addProjectPermission(UserRole.USER, project); userSession.addProjectPermission(USER, project); - MetricDto metric = db.measures().insertMetric(m -> m.setValueType(INT.name())); + MetricDto metric = db.measures().insertMetric(m -> m.setValueType("INT")); ComponentWsResponse response = ws.newRequest() .setParam("componentId", project.uuid()) @@ -214,7 +212,7 @@ public class ComponentActionTest { ComponentDto project = db.components().insertPrivateProject(); userSession.addProjectPermission(UserRole.USER, project); userSession.addProjectPermission(USER, project); - MetricDto metric = db.measures().insertMetric(m -> m.setValueType(INT.name())); + MetricDto metric = db.measures().insertMetric(m -> m.setValueType("INT")); ComponentWsResponse response = ws.newRequest() .setParam("componentKey", project.getKey()) @@ -229,7 +227,7 @@ public class ComponentActionTest { ComponentDto project = db.components().insertPrivateProject(); userSession.addProjectPermission(UserRole.USER, project); MetricDto metricWithoutDomain = db.measures().insertMetric(m -> m - .setValueType(Measure.ValueType.INT.name()) + .setValueType("INT") .setDomain(null)); db.measures().insertLiveMeasure(project, metricWithoutDomain); @@ -251,7 +249,7 @@ public class ComponentActionTest { ComponentDto file = db.components().insertComponent(newFileDto(project)); userSession.addProjectPermission(UserRole.USER, project); MetricDto metric = db.measures().insertMetric(m -> m - .setValueType(Measure.ValueType.INT.name()) + .setValueType("INT") .setBestValue(7.0d) .setOptimizedBestValue(true) .setDomain(null)); @@ -273,7 +271,7 @@ public class ComponentActionTest { userSession.addProjectPermission(UserRole.USER, project); db.components().insertSnapshot(project); - MetricDto metric = db.measures().insertMetric(m -> m.setValueType(INT.name())); + MetricDto metric = db.measures().insertMetric(m -> m.setValueType("INT")); expectedException.expect(NotFoundException.class); expectedException.expectMessage("The Developer Cockpit feature has been dropped. The specified developer cannot be found."); @@ -289,8 +287,8 @@ public class ComponentActionTest { ComponentDto project = db.components().insertPrivateProject(); userSession.addProjectPermission(UserRole.USER, project); db.components().insertSnapshot(project); - db.measures().insertMetric(m -> m.setKey("ncloc").setValueType(INT.name())); - db.measures().insertMetric(m -> m.setKey("complexity").setValueType(INT.name())); + db.measures().insertMetric(m -> m.setKey("ncloc").setValueType("INT")); + db.measures().insertMetric(m -> m.setKey("complexity").setValueType("INT")); expectedException.expect(NotFoundException.class); expectedException.expectMessage("The following metric keys are not found: unknown-metric, another-unknown-metric"); @@ -315,7 +313,7 @@ public class ComponentActionTest { userSession.logIn(); ComponentDto project = db.components().insertPrivateProject(); db.components().insertSnapshot(project); - MetricDto metric = db.measures().insertMetric(m -> m.setValueType(INT.name())); + MetricDto metric = db.measures().insertMetric(m -> m.setValueType("INT")); expectedException.expect(ForbiddenException.class); @@ -324,7 +322,7 @@ public class ComponentActionTest { @Test public void fail_when_component_does_not_exist() { - MetricDto metric = db.measures().insertMetric(m -> m.setValueType(INT.name())); + MetricDto metric = db.measures().insertMetric(m -> m.setValueType("INT")); expectedException.expect(NotFoundException.class); expectedException.expectMessage("Component key 'project-key' not found"); @@ -340,7 +338,7 @@ public class ComponentActionTest { ComponentDto project = db.components().insertPrivateProject(p -> p.setEnabled(false)); userSession.addProjectPermission(UserRole.USER, project); userSession.addProjectPermission(USER, project); - MetricDto metric = db.measures().insertMetric(m -> m.setValueType(INT.name())); + MetricDto metric = db.measures().insertMetric(m -> m.setValueType("INT")); expectedException.expect(NotFoundException.class); expectedException.expectMessage(String.format("Component key '%s' not found", project.getKey())); @@ -391,7 +389,7 @@ public class ComponentActionTest { ComponentDto project = db.components().insertMainBranch(organization); userSession.logIn().addProjectPermission(UserRole.USER, project); ComponentDto branch = db.components().insertProjectBranch(project); - MetricDto metric = db.measures().insertMetric(m -> m.setValueType(INT.name())); + MetricDto metric = db.measures().insertMetric(m -> m.setValueType("INT")); expectedException.expect(NotFoundException.class); expectedException.expectMessage(format("Component key '%s' not found", branch.getDbKey())); @@ -408,7 +406,7 @@ public class ComponentActionTest { ComponentDto project = db.components().insertMainBranch(organization); userSession.logIn().addProjectPermission(UserRole.USER, project); ComponentDto branch = db.components().insertProjectBranch(project); - MetricDto metric = db.measures().insertMetric(m -> m.setValueType(INT.name())); + MetricDto metric = db.measures().insertMetric(m -> m.setValueType("INT")); expectedException.expect(NotFoundException.class); expectedException.expectMessage(format("Component id '%s' not found", branch.uuid())); diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ConditionEvaluatorTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ConditionEvaluatorTest.java index f8b4234992c..8f73faf337c 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ConditionEvaluatorTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ConditionEvaluatorTest.java @@ -216,221 +216,4 @@ public class ConditionEvaluatorTest { } } - // @Test - // public void testEquals_for_String() { - // Metric metric = createMetric(STRING); - // Measure measure = newMeasureBuilder().create("TEST"); - // - // EvaluationResultAssert.assertThat(underTest.evaluate(createErrorCondition(metric, EQUALS, "TEST"), - // measure)).hasLevel(ERROR).hasValue("TEST"); - // EvaluationResultAssert.assertThat(underTest.evaluate(createErrorCondition(metric, EQUALS, "TEST2"), - // measure)).hasLevel(OK).hasValue("TEST"); - // } - // - // @Test - // - // public void testNotEquals() { - // Metric metric = createMetric(STRING); - // Measure measure = newMeasureBuilder().create("TEST"); - // - // EvaluationResultAssert.assertThat(underTest.evaluate(createErrorCondition(metric, NOT_EQUALS, "TEST"), - // measure)).hasLevel(OK).hasValue("TEST"); - // EvaluationResultAssert.assertThat(underTest.evaluate(createErrorCondition(metric, NOT_EQUALS, "TEST2"), - // measure)).hasLevel(ERROR).hasValue("TEST"); - // } - // - // @Test - // public void testEquals_Percent() { - // Metric metric = createMetric(PERCENT); - // Measure measure = newMeasureBuilder().create(10.2d, 1, null); - // - // EvaluationResultAssert.assertThat(underTest.evaluate(createErrorCondition(metric, EQUALS, "10.2"), - // measure)).hasLevel(ERROR).hasValue(10.2d); - // } - // - // @Test - // public void testEquals_Float() { - // Metric metric = createMetric(PERCENT); - // Measure measure = newMeasureBuilder().create(10.2d, 1, null); - // - // EvaluationResultAssert.assertThat(underTest.evaluate(createErrorCondition(metric, EQUALS, "10.2"), - // measure)).hasLevel(ERROR).hasValue(10.2d); - // } - // - // @Test - // public void testEquals_Int() { - // Metric metric = createMetric(INT); - // Measure measure = newMeasureBuilder().create(10, null); - // - // EvaluationResultAssert.assertThat(underTest.evaluate(createErrorCondition(metric, EQUALS, "10"), measure)).hasLevel(ERROR).hasValue(10); - // EvaluationResultAssert.assertThat(underTest.evaluate(createErrorCondition(metric, EQUALS, "10.2"), - // measure)).hasLevel(ERROR).hasValue(10); - // } - // - // @Test - // public void testEquals_Level() { - // Metric metric = createMetric(LEVEL); - // Measure measure = newMeasureBuilder().create(ERROR); - // - // EvaluationResultAssert.assertThat(underTest.evaluate(createErrorCondition(metric, EQUALS, ERROR.name()), - // measure)).hasLevel(ERROR).hasValue(ERROR.name()); - // - // EvaluationResultAssert.assertThat(underTest.evaluate(createErrorCondition(metric, EQUALS, OK.name()), - // measure)).hasLevel(OK).hasValue(ERROR.name()); - // } - // - // @Test - // public void testNotEquals_Level() { - // Metric metric = createMetric(LEVEL); - // Measure measure = newMeasureBuilder().create(ERROR); - // - // EvaluationResultAssert.assertThat(underTest.evaluate(createErrorCondition(metric, NOT_EQUALS, OK.name()), - // measure)).hasLevel(ERROR).hasValue(ERROR.name()); - // } - // - // @Test - // public void testEquals_BOOL() { - // Metric metric = createMetric(BOOL); - // Measure measure = newMeasureBuilder().create(false, null); - // - // EvaluationResultAssert.assertThat(underTest.evaluate(createErrorCondition(metric, EQUALS, "1"), measure)).hasLevel(OK).hasValue(false); - // EvaluationResultAssert.assertThat(underTest.evaluate(createErrorCondition(metric, EQUALS, "0"), - // measure)).hasLevel(ERROR).hasValue(false); - // } - // - // @Test - // public void testNotEquals_BOOL() { - // Metric metric = createMetric(BOOL); - // Measure measure = newMeasureBuilder().create(false, null); - // - // EvaluationResultAssert.assertThat(underTest.evaluate(createErrorCondition(metric, NOT_EQUALS, "1"), - // measure)).hasLevel(ERROR).hasValue(false); - // EvaluationResultAssert.assertThat(underTest.evaluate(createErrorCondition(metric, NOT_EQUALS, "0"), - // measure)).hasLevel(OK).hasValue(false); - // } - // - // @Test - // public void getLevel_throws_IEA_if_error_threshold_is_not_parsable_boolean() { - // Metric metric = createMetric(BOOL); - // Measure measure = newMeasureBuilder().create(false, null); - // - // expectedException.expect(IllegalArgumentException.class); - // expectedException.expectMessage("Quality Gate: Unable to parse value 'polop' to compare against name"); - // - // underTest.evaluate(createErrorCondition(metric, EQUALS, "polop"), measure); - // } - // - // @Test - // public void testEquals_work_duration() { - // Metric metric = createMetric(WORK_DUR); - // Measure measure = newMeasureBuilder().create(60l, null); - // - // EvaluationResultAssert.assertThat(underTest.evaluate(createErrorCondition(metric, EQUALS, "60"), measure)).hasLevel(ERROR); - // } - // - // @Test - // public void getLevel_throws_IEA_if_error_threshold_is_not_parsable_long() { - // Metric metric = createMetric(WORK_DUR); - // Measure measure = newMeasureBuilder().create(60l, null); - // - // expectedException.expect(IllegalArgumentException.class); - // expectedException.expectMessage("Quality Gate: Unable to parse value 'polop' to compare against name"); - // - // underTest.evaluate(createErrorCondition(metric, EQUALS, "polop"), measure); - // } - // - // @Test - // public void testErrorAndWarningLevel() { - // Metric metric = createMetric(FLOAT); - // Measure measure = newMeasureBuilder().create(10.2d, 1, null); - // - // EvaluationResultAssert.assertThat(underTest.evaluate(createErrorCondition(metric, EQUALS, "10.2"), measure)).hasLevel(ERROR); - // EvaluationResultAssert.assertThat(underTest.evaluate(createErrorCondition(metric, EQUALS, "10.1"), measure)).hasLevel(OK); - // - // EvaluationResultAssert.assertThat(underTest.evaluate(new org.sonar.server.computation.task.projectanalysis.qualitygate.Condition(metric, - // EQUALS.getDbValue(), "10.3", "10.2", false), measure)).hasLevel(Measure.Level.WARN); - // EvaluationResultAssert.assertThat(underTest.evaluate(new org.sonar.server.computation.task.projectanalysis.qualitygate.Condition(metric, - // LESS_THAN.getDbValue(), "10.3", "10.2", false), measure)).hasLevel(Measure.Level.ERROR); - // } - // - // @Test - // public void condition_is_always_ok_when_measure_is_noValue() { - // for (Metric.MetricType metricType : from(asList(values())).filter(not(in(ImmutableSet.of(DATA, LEVEL))))) { - // Metric metric = createMetric(metricType); - // Measure measure = newMeasureBuilder().createNoValue(); - // - // EvaluationResultAssert.assertThat(underTest.evaluate(createErrorCondition(metric, EQUALS, "10.2"), measure)).hasLevel(OK); - // } - // } - // - // @Test - // public void testUnsupportedType() { - // Metric metric = createMetric(DATA); - // Measure measure = newMeasureBuilder().create("3.14159265358"); - // - // expectedException.expect(IllegalArgumentException.class); - // expectedException.expectMessage("Conditions on MetricType DATA are not supported"); - // - // underTest.evaluate(createErrorCondition(metric, EQUALS, "1.60217657"), measure); - // } - // - // @Test - // public void condition_on_period() { - // for (Metric.MetricType metricType : ImmutableList.of(FLOAT, INT, WORK_DUR)) { - // Metric metric = createMetric(metricType); - // Measure measure = newMeasureBuilder().setVariation(3d).createNoValue(); - // - // EvaluationResultAssert.assertThat(underTest.evaluate(new org.sonar.server.computation.task.projectanalysis.qualitygate.Condition(metric, - // GREATER_THAN.getDbValue(), "3", null, true), measure)).hasLevel(OK); - // } - // } - // - // @Test - // public void condition_on_period_without_value_is_OK() { - // Metric metric = createMetric(FLOAT); - // Measure measure = newMeasureBuilder().createNoValue(); - // - // EvaluationResultAssert.assertThat(underTest.evaluate(new org.sonar.server.computation.task.projectanalysis.qualitygate.Condition(metric, - // GREATER_THAN.getDbValue(), "3", null, true), measure)).hasLevel(OK).hasValue(null); - // } - // - // @Test - // public void condition_on_rating() throws Exception { - // Metric metric = createMetric(RATING); - // Measure measure = newMeasureBuilder().create(4, "D"); - // - // EvaluationResultAssert.assertThat(underTest.evaluate(new org.sonar.server.computation.task.projectanalysis.qualitygate.Condition(metric, - // GREATER_THAN.getDbValue(), "4", null, false), measure)).hasLevel(OK).hasValue(4); - // EvaluationResultAssert.assertThat(underTest.evaluate(new org.sonar.server.computation.task.projectanalysis.qualitygate.Condition(metric, - // GREATER_THAN.getDbValue(), "2", null, false), measure)).hasLevel(ERROR).hasValue(4); - // } - // - // @Test - // public void condition_on_rating_on_leak_period() throws Exception { - // Metric metric = createMetric(RATING); - // Measure measure = newMeasureBuilder().setVariation(4d).createNoValue(); - // - // EvaluationResultAssert.assertThat(underTest.evaluate(new org.sonar.server.computation.task.projectanalysis.qualitygate.Condition(metric, - // GREATER_THAN.getDbValue(), "5", null, true), measure)).hasLevel(OK).hasValue(4); - // EvaluationResultAssert.assertThat(underTest.evaluate(new org.sonar.server.computation.task.projectanalysis.qualitygate.Condition(metric, - // GREATER_THAN.getDbValue(), "2", null, true), measure)).hasLevel(ERROR).hasValue(4); - // } - // - // @Test - // public void condition_on_rating_on_leak_period_when_variation_is_zero() throws Exception { - // Metric metric = createMetric(RATING); - // Measure measure = newMeasureBuilder().setVariation(0d).createNoValue(); - // - // EvaluationResultAssert.assertThat(underTest.evaluate(new org.sonar.server.computation.task.projectanalysis.qualitygate.Condition(metric, - // GREATER_THAN.getDbValue(), "4", null, true), measure)).hasLevel(OK).hasValue(0); - // } - // - // private static org.sonar.server.computation.task.projectanalysis.qualitygate.Condition createErrorCondition(Metric metric, - // org.sonar.server.computation.task.projectanalysis.qualitygate.Condition.Operator operator, String errorThreshold) { - // return new Condition(metric, operator.getDbValue(), errorThreshold, null, false); - // } - // - // private static MetricImpl createMetric(Metric.MetricType metricType) { - // return new MetricImpl(1, "key", "name", metricType); - // } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/ExternalRuleCreatorTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/ExternalRuleCreatorTest.java index ac55073f183..32b9d329e79 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/rule/ExternalRuleCreatorTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/rule/ExternalRuleCreatorTest.java @@ -24,8 +24,7 @@ import org.sonar.api.rule.RuleKey; import org.sonar.api.utils.System2; import org.sonar.db.DbSession; import org.sonar.db.DbTester; -import org.sonar.server.computation.task.projectanalysis.issue.NewExternalRule; -import org.sonar.server.computation.task.projectanalysis.issue.Rule; +import org.sonar.db.rule.RuleDto; import org.sonar.server.es.EsTester; import org.sonar.server.rule.index.RuleIndexer; @@ -51,7 +50,7 @@ public class ExternalRuleCreatorTest { .setName("name") .build(); - Rule rule1 = underTest.persistAndIndex(dbSession, externalRule); + RuleDto rule1 = underTest.persistAndIndex(dbSession, externalRule); assertThat(rule1).isNotNull(); assertThat(rule1.isExternal()).isTrue(); @@ -59,7 +58,7 @@ public class ExternalRuleCreatorTest { assertThat(rule1.getKey()).isEqualTo(ruleKey); assertThat(rule1.getPluginKey()).isEqualTo("eslint"); assertThat(rule1.getName()).isEqualTo("name"); - assertThat(rule1.getType()).isNull(); + assertThat(rule1.getType()).isEqualTo(0); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/NewExternalRuleTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/NewExternalRuleTest.java new file mode 100644 index 00000000000..85816da9e6b --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/rule/NewExternalRuleTest.java @@ -0,0 +1,55 @@ +/* + * 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.junit.rules.ExpectedException; +import org.sonar.api.rule.RuleKey; + +import static org.assertj.core.api.Assertions.assertThat; + +public class NewExternalRuleTest { + @org.junit.Rule + public ExpectedException exception = ExpectedException.none(); + + @Test + public void should_build_new_external_rule() { + NewExternalRule.Builder builder = new NewExternalRule.Builder() + .setKey(RuleKey.of("repo", "rule")) + .setPluginKey("repo") + .setName("name"); + + assertThat(builder.name()).isEqualTo("name"); + + NewExternalRule rule = builder.build(); + + assertThat(rule.getName()).isEqualTo("name"); + assertThat(rule.getPluginKey()).isEqualTo("repo"); + } + + @Test + public void fail_if_rule_key_is_not_set() { + exception.expect(NullPointerException.class); + exception.expectMessage("'key' not expected to be null for an external rule"); + + new NewExternalRule.Builder() + .build(); + } +}