import java.util.ArrayList;
import java.util.List;
import java.util.Set;
+import java.util.TreeSet;
import org.sonar.core.util.stream.Collectors;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
}
public void validate(DbSession dbSession, ProjectMeasuresQuery query) {
- List<String> metricKeys = new ArrayList<>(query.getMetricCriteria().stream().map(MetricCriterion::getMetricKey).collect(Collectors.toSet()));
- List<MetricDto> dbMetrics = dbClient.metricDao().selectByKeys(dbSession, metricKeys);
- if (dbMetrics.size() == metricKeys.size()) {
+ Set<String> metricKeys = query.getMetricCriteria().stream().map(MetricCriterion::getMetricKey).collect(Collectors.toSet());
+ if (metricKeys.isEmpty()) {
return;
}
- List<String> metricDtoKeys = dbMetrics.stream().map(MetricDto::getKey).collect(Collectors.toList());
- Set<String> unknownKeys = metricKeys.stream().filter(metricKey -> !metricDtoKeys.contains(metricKey)).collect(Collectors.toSet());
- throw new IllegalArgumentException(String.format("Unknown metric(s) %s", unknownKeys));
+ List<MetricDto> dbMetrics = dbClient.metricDao().selectByKeys(dbSession, new ArrayList<>(metricKeys));
+ checkMetricKeysExists(dbMetrics, metricKeys);
+ checkMetricsAreEnabledAndVisible(dbMetrics);
+ checkMetricsAreNumerics(dbMetrics);
}
+
+ private static void checkMetricKeysExists(List<MetricDto> dbMetrics, Set<String> inputMetricKeys) {
+ Set<String> dbMetricsKeys = dbMetrics.stream().map(MetricDto::getKey).collect(Collectors.toSet());
+ Set<String> unknownKeys = inputMetricKeys.stream().filter(metricKey -> !dbMetricsKeys.contains(metricKey)).collect(Collectors.toSet());
+ if (!unknownKeys.isEmpty()) {
+ throw new IllegalArgumentException(String.format("Unknown metric(s) %s", new TreeSet<>(unknownKeys)));
+ }
+ }
+
+ private static void checkMetricsAreEnabledAndVisible(List<MetricDto> dbMetrics) {
+ Set<String> invalidKeys = dbMetrics.stream()
+ .filter(metricDto -> !metricDto.isEnabled() || metricDto.isHidden())
+ .map(MetricDto::getKey)
+ .collect(Collectors.toSet());
+ if (!invalidKeys.isEmpty()) {
+ throw new IllegalArgumentException(String.format("Following metrics are disabled or hidden : %s", new TreeSet<>(invalidKeys)));
+ }
+ }
+
+ private static void checkMetricsAreNumerics(List<MetricDto> dbMetrics) {
+ Set<String> invalidKeys = dbMetrics.stream()
+ .filter(MetricDto::isDataType)
+ .map(MetricDto::getKey)
+ .collect(Collectors.toSet());
+ if (!invalidKeys.isEmpty()) {
+ throw new IllegalArgumentException(String.format("Following metrics are not numeric : %s", new TreeSet<>(invalidKeys)));
+ }
+ }
+
}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact 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.component.ws;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.sonar.api.utils.System2;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.DbTester;
-import org.sonar.db.metric.MetricTesting;
-
-public class ProjectMeasuresQueryFactoryValidatorTest {
-
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
-
- @Rule
- public DbTester db = DbTester.create(System2.INSTANCE);
-
- DbClient dbClient = db.getDbClient();
- DbSession dbSession = db.getSession();
-
- ProjectMeasuresQueryValidator validator = new ProjectMeasuresQueryValidator(dbClient);
-
- @Test
- public void does_not_fail_when_metric_criteria_contains_an_existing_metric() throws Exception {
- insertMetric("ncloc");
-
- validator.validate(dbSession, ProjectMeasuresQueryFactory.newProjectMeasuresQuery("ncloc > 10"));
- }
-
- @Test
- public void fail_when_metric_does_not_exists() throws Exception {
- insertMetric("ncloc");
-
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Unknown metric(s) [unknown]");
- validator.validate(dbSession, ProjectMeasuresQueryFactory.newProjectMeasuresQuery("unknown > 10"));
- }
-
- @Test
- public void return_all_unknown_metrics() throws Exception {
- insertMetric("ncloc");
-
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Unknown metric(s) [coverage, debt]");
- validator.validate(dbSession, ProjectMeasuresQueryFactory.newProjectMeasuresQuery("debt > 10 AND ncloc <= 20 AND coverage > 30"));
- }
-
- private void insertMetric(String metricKey) {
- dbClient.metricDao().insert(dbSession, MetricTesting.newMetricDto().setKey(metricKey));
- }
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact 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.component.ws;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.DbTester;
+import org.sonar.db.metric.MetricDto;
+
+import static org.sonar.api.measures.Metric.ValueType.DATA;
+import static org.sonar.api.measures.Metric.ValueType.DISTRIB;
+import static org.sonar.api.measures.Metric.ValueType.INT;
+import static org.sonar.api.measures.Metric.ValueType.WORK_DUR;
+import static org.sonar.db.metric.MetricTesting.newMetricDto;
+import static org.sonar.server.component.ws.ProjectMeasuresQueryFactory.newProjectMeasuresQuery;
+
+public class ProjectMeasuresQueryValidatorTest {
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ @Rule
+ public DbTester db = DbTester.create(System2.INSTANCE);
+
+ DbClient dbClient = db.getDbClient();
+ DbSession dbSession = db.getSession();
+
+ ProjectMeasuresQueryValidator validator = new ProjectMeasuresQueryValidator(dbClient);
+
+ @Test
+ public void query_with_empty_metrics_is_valid() throws Exception {
+ validator.validate(dbSession, newProjectMeasuresQuery(""));
+ }
+
+ @Test
+ public void does_not_fail_when_metric_criteria_contains_an_existing_metric() throws Exception {
+ insertValidMetric("ncloc");
+
+ validator.validate(dbSession, newProjectMeasuresQuery("ncloc > 10"));
+ }
+
+ @Test
+ public void fail_when_metric_are_not_numeric() throws Exception {
+ insertMetric(createValidMetric("ncloc").setValueType(INT.name()));
+ insertMetric(createValidMetric("debt").setValueType(WORK_DUR.name()));
+ insertMetric(createValidMetric("data").setValueType(DATA.name()));
+ insertMetric(createValidMetric("distrib").setValueType(DISTRIB.name()));
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Following metrics are not numeric : [data, distrib]");
+ validator.validate(dbSession, newProjectMeasuresQuery("data > 10 and distrib = 11 and ncloc <= 20 and debt < 30"));
+ }
+
+ @Test
+ public void fail_when_metric_is_hidden() throws Exception {
+ insertMetric(createValidMetric("ncloc").setHidden(true));
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Following metrics are disabled or hidden : [ncloc]");
+ validator.validate(dbSession, newProjectMeasuresQuery("ncloc > 10"));
+ }
+
+ @Test
+ public void fail_when_metric_is_disabled() throws Exception {
+ insertMetric(createValidMetric("ncloc").setEnabled(false));
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Following metrics are disabled or hidden : [ncloc]");
+ validator.validate(dbSession, newProjectMeasuresQuery("ncloc > 10"));
+ }
+
+ @Test
+ public void fail_when_metric_does_not_exists() throws Exception {
+ insertValidMetric("ncloc");
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Unknown metric(s) [unknown]");
+ validator.validate(dbSession, newProjectMeasuresQuery("unknown > 10"));
+ }
+
+ @Test
+ public void return_all_unknown_metrics() throws Exception {
+ insertValidMetric("ncloc");
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Unknown metric(s) [coverage, debt]");
+ validator.validate(dbSession, newProjectMeasuresQuery("debt > 10 AND ncloc <= 20 AND coverage > 30"));
+ }
+
+ private void insertValidMetric(String metricKey) {
+ insertMetric(createValidMetric(metricKey));
+ }
+
+ private void insertMetric(MetricDto metricDto) {
+ dbClient.metricDao().insert(dbSession, metricDto);
+ }
+
+ private static MetricDto createValidMetric(String metricKey) {
+ return newMetricDto().setKey(metricKey).setValueType(INT.name()).setEnabled(true).setHidden(false);
+ }
+}
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.config.MapSettings;
-import org.sonar.api.measures.Metric;
import org.sonar.api.security.DefaultGroups;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.server.ws.WebService.Param;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.tuple;
+import static org.sonar.api.measures.Metric.ValueType.INT;
import static org.sonar.db.component.ComponentTesting.newDeveloper;
import static org.sonar.db.component.ComponentTesting.newDirectory;
import static org.sonar.db.component.ComponentTesting.newFileDto;
insertProjectInDbAndEs(newProjectDto().setName("Sonar Java"), newArrayList(newMeasure(COVERAGE, 81), newMeasure(NCLOC, 10_000d)));
insertProjectInDbAndEs(newProjectDto().setName("Sonar Markdown"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 10_000d)));
insertProjectInDbAndEs(newProjectDto().setName("Sonar Qube"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 10_001d)));
+ insertMetrics(COVERAGE, NCLOC);
request.setFilter("coverage <= 80 and ncloc <= 10000");
- dbClient.metricDao().insert(dbSession, newMetricDto().setKey(COVERAGE).setValueType(Metric.ValueType.FLOAT.name()));
- dbClient.metricDao().insert(dbSession, newMetricDto().setKey(NCLOC).setValueType(Metric.ValueType.FLOAT.name()));
- db.commit();
SearchProjectsWsResponse result = call(request);
insertProjectInDbAndEs(newProjectDto().setName("Sonar Groovy"), newArrayList(newMeasure(COVERAGE, 81), newMeasure(NCLOC, 5d)));
insertProjectInDbAndEs(newProjectDto().setName("Sonar Markdown"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 10_000d)));
insertProjectInDbAndEs(newProjectDto().setName("Sonar Qube"), newArrayList(newMeasure(COVERAGE, 80d), newMeasure(NCLOC, 500_001d)));
- dbClient.metricDao().insert(dbSession, newMetricDto().setKey(COVERAGE).setValueType(Metric.ValueType.FLOAT.name()));
- dbClient.metricDao().insert(dbSession, newMetricDto().setKey(NCLOC).setValueType(Metric.ValueType.FLOAT.name()));
- db.commit();
-
+ insertMetrics(COVERAGE, NCLOC);
SearchProjectsWsResponse result = call(request);
Common.Facet facet = result.getFacets().getFacetsList().stream()
}
}
+ private void insertMetrics(String... metricKeys) {
+ for (String metricKey : metricKeys) {
+ dbClient.metricDao().insert(dbSession, newMetricDto().setKey(metricKey).setValueType(INT.name()).setEnabled(true).setHidden(false));
+ }
+ dbSession.commit();
+ }
+
private static Map<String, Object> newMeasure(String key, double value) {
return ImmutableMap.of("key", key, "value", value);
}