From 6e71f912a66cf1c7045e8f2432b62234d5d811a1 Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Fri, 19 May 2017 17:13:18 +0200 Subject: [PATCH] SONAR-9245 facet new_coverage in search_projects WS --- .../it/projectSearch/SearchProjectsTest.java | 8 +- .../measure/index/ProjectMeasuresIndex.java | 7 +- .../ws/SearchProjectsActionTest.java | 80 ++++++++++++++++++- .../index/ProjectMeasuresIndexTest.java | 36 +++++++++ 4 files changed, 128 insertions(+), 3 deletions(-) diff --git a/it/it-tests/src/test/java/it/projectSearch/SearchProjectsTest.java b/it/it-tests/src/test/java/it/projectSearch/SearchProjectsTest.java index 1f6e2c9cae9..a8bc32a5250 100644 --- a/it/it-tests/src/test/java/it/projectSearch/SearchProjectsTest.java +++ b/it/it-tests/src/test/java/it/projectSearch/SearchProjectsTest.java @@ -200,7 +200,7 @@ public class SearchProjectsTest { analyzeProject(projectKey, "shared/xoo-history-v2"); SearchProjectsWsResponse response = searchProjects(SearchProjectsRequest.builder().setOrganization(organizationKey).setFacets(asList( - "new_reliability_rating", "new_security_rating", "new_maintainability_rating")).build()); + "new_reliability_rating", "new_security_rating", "new_maintainability_rating", "new_coverage")).build()); checkFacet(response, "new_reliability_rating", tuple("1", 1L), @@ -220,6 +220,12 @@ public class SearchProjectsTest { tuple("3", 0L), tuple("4", 0L), tuple("5", 0L)); + checkFacet(response, "new_coverage", + tuple("*-30.0", 0L), + tuple("30.0-50.0", 0L), + tuple("50.0-70.0", 0L), + tuple("70.0-80.0", 0L), + tuple("80.0-*", 0L)); } private void checkFacet(SearchProjectsWsResponse response, String facetKey, Tuple... values) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/index/ProjectMeasuresIndex.java b/server/sonar-server/src/main/java/org/sonar/server/measure/index/ProjectMeasuresIndex.java index e548ddec2ec..df8e17a7bbf 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/measure/index/ProjectMeasuresIndex.java +++ b/server/sonar-server/src/main/java/org/sonar/server/measure/index/ProjectMeasuresIndex.java @@ -65,6 +65,7 @@ import static org.sonar.api.measures.CoreMetrics.ALERT_STATUS_KEY; import static org.sonar.api.measures.CoreMetrics.COVERAGE_KEY; import static org.sonar.api.measures.CoreMetrics.DUPLICATED_LINES_DENSITY_KEY; import static org.sonar.api.measures.CoreMetrics.NCLOC_KEY; +import static org.sonar.api.measures.CoreMetrics.NEW_COVERAGE_KEY; import static org.sonar.api.measures.CoreMetrics.NEW_MAINTAINABILITY_RATING_KEY; import static org.sonar.api.measures.CoreMetrics.NEW_RELIABILITY_RATING_KEY; import static org.sonar.api.measures.CoreMetrics.NEW_SECURITY_RATING_KEY; @@ -91,6 +92,7 @@ public class ProjectMeasuresIndex { NCLOC_KEY, DUPLICATED_LINES_DENSITY_KEY, COVERAGE_KEY, + NEW_COVERAGE_KEY, SQALE_RATING_KEY, NEW_MAINTAINABILITY_RATING_KEY, RELIABILITY_RATING_KEY, @@ -101,13 +103,16 @@ public class ProjectMeasuresIndex { FILTER_LANGUAGES, FILTER_TAGS); + private static final Double[] COVERAGE_THRESHOLDS = new Double[]{30d, 50d, 70d, 80d}; + private static final String FIELD_MEASURES_KEY = FIELD_MEASURES + "." + ProjectMeasuresIndexDefinition.FIELD_MEASURES_KEY; private static final String FIELD_MEASURES_VALUE = FIELD_MEASURES + "." + ProjectMeasuresIndexDefinition.FIELD_MEASURES_VALUE; private static final Map FACET_FACTORIES = ImmutableMap.builder() .put(NCLOC_KEY, (esSearch, query, facetBuilder) -> addRangeFacet(esSearch, NCLOC_KEY, facetBuilder, 1_000d, 10_000d, 100_000d, 500_000d)) .put(DUPLICATED_LINES_DENSITY_KEY, (esSearch, query, facetBuilder) -> addRangeFacet(esSearch, DUPLICATED_LINES_DENSITY_KEY, facetBuilder, 3d, 5d, 10d, 20d)) - .put(COVERAGE_KEY, (esSearch, query, facetBuilder) -> addRangeFacet(esSearch, COVERAGE_KEY, facetBuilder, 30d, 50d, 70d, 80d)) + .put(COVERAGE_KEY, (esSearch, query, facetBuilder) -> addRangeFacet(esSearch, COVERAGE_KEY, facetBuilder, COVERAGE_THRESHOLDS)) + .put(NEW_COVERAGE_KEY, (esSearch, query, facetBuilder) -> addRangeFacet(esSearch, NEW_COVERAGE_KEY, facetBuilder, COVERAGE_THRESHOLDS)) .put(SQALE_RATING_KEY, (esSearch, query, facetBuilder) -> addRatingFacet(esSearch, SQALE_RATING_KEY, facetBuilder)) .put(NEW_MAINTAINABILITY_RATING_KEY, (esSearch, query, facetBuilder) -> addRatingFacet(esSearch, NEW_MAINTAINABILITY_RATING_KEY, facetBuilder)) .put(RELIABILITY_RATING_KEY, (esSearch, query, facetBuilder) -> addRatingFacet(esSearch, RELIABILITY_RATING_KEY, facetBuilder)) 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 398f78ab8a9..31511f8bdfd 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 @@ -84,6 +84,7 @@ 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.es.ProjectIndexer.Cause.PROJECT_CREATION; import static org.sonar.test.JsonAssert.assertJson; @@ -97,6 +98,7 @@ public class SearchProjectsActionTest { private static final String NCLOC = "ncloc"; private static final String COVERAGE = "coverage"; + private static final String NEW_COVERAGE = "new_coverage"; private static final String QUALITY_GATE_STATUS = "alert_status"; private static final String IS_FAVOURITE_CRITERION = "isFavorite"; @@ -167,7 +169,7 @@ public class SearchProjectsActionTest { Param facets = def.param("facets"); assertThat(facets.defaultValue()).isNull(); assertThat(facets.possibleValues()).containsOnly("ncloc", "duplicated_lines_density", "coverage", "sqale_rating", "reliability_rating", "security_rating", "alert_status", - "languages", "tags", "new_reliability_rating", "new_security_rating", "new_maintainability_rating"); + "languages", "tags", "new_reliability_rating", "new_security_rating", "new_maintainability_rating", "new_coverage"); } @Test @@ -354,6 +356,34 @@ public class SearchProjectsActionTest { assertThat(result.getComponentsList()).extracting(Component::getKey).containsExactlyInAnyOrder(project1.getKey(), project3.getKey()); } + @Test + public void filter_projects_by_coverage() { + userSession.logIn(); + OrganizationDto organizationDto = db.organizations().insert(); + MetricDto coverage = db.measureDbTester().insertMetric(c -> c.setKey(COVERAGE).setValueType(PERCENT.name())); + 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))); + + SearchProjectsWsResponse result = call(request.setFilter("coverage <= 80")); + + assertThat(result.getComponentsList()).extracting(Component::getKey).containsExactlyInAnyOrder(project1.getKey(), project3.key()); + } + + @Test + public void filter_projects_by_new_coverage() { + userSession.logIn(); + OrganizationDto organizationDto = db.organizations().insert(); + MetricDto coverage = db.measureDbTester().insertMetric(c -> c.setKey(NEW_COVERAGE).setValueType(PERCENT.name())); + 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))); + + SearchProjectsWsResponse result = call(request.setFilter("new_coverage <= 80")); + + assertThat(result.getComponentsList()).extracting(Component::getKey).containsExactlyInAnyOrder(project1.getKey(), project3.key()); + } + @Test public void filter_projects_by_text_query() { userSession.logIn(); @@ -619,6 +649,54 @@ public class SearchProjectsActionTest { tuple("5", 1L)); } + @Test + public void return_coverage_facet() { + userSession.logIn(); + OrganizationDto organizationDto = db.organizations().insert(); + MetricDto coverage = db.measureDbTester().insertMetric(c -> c.setKey(COVERAGE).setValueType(PERCENT.name())); + insertProject(organizationDto, new Measure(coverage, c -> c.setValue(80d))); + insertProject(organizationDto, new Measure(coverage, c -> c.setValue(85d))); + insertProject(organizationDto, new Measure(coverage, c -> c.setValue(10d))); + + SearchProjectsWsResponse result = call(request.setFacets(singletonList(COVERAGE))); + + Common.Facet facet = result.getFacets().getFacetsList().stream() + .filter(oneFacet -> COVERAGE.equals(oneFacet.getProperty())) + .findFirst().orElseThrow(IllegalStateException::new); + assertThat(facet.getValuesList()) + .extracting(Common.FacetValue::getVal, Common.FacetValue::getCount) + .containsExactly( + tuple("*-30.0", 1L), + tuple("30.0-50.0", 0L), + tuple("50.0-70.0", 0L), + tuple("70.0-80.0", 0L), + tuple("80.0-*", 2L)); + } + + @Test + public void return_new_coverage_facet() { + userSession.logIn(); + OrganizationDto organizationDto = db.organizations().insert(); + MetricDto coverage = db.measureDbTester().insertMetric(c -> c.setKey(NEW_COVERAGE).setValueType(PERCENT.name())); + insertProject(organizationDto, new Measure(coverage, c -> c.setVariation(80d))); + insertProject(organizationDto, new Measure(coverage, c -> c.setVariation(85d))); + insertProject(organizationDto, new Measure(coverage, c -> c.setVariation(10d))); + + SearchProjectsWsResponse result = call(request.setFacets(singletonList(NEW_COVERAGE))); + + Common.Facet facet = result.getFacets().getFacetsList().stream() + .filter(oneFacet -> NEW_COVERAGE.equals(oneFacet.getProperty())) + .findFirst().orElseThrow(IllegalStateException::new); + assertThat(facet.getValuesList()) + .extracting(Common.FacetValue::getVal, Common.FacetValue::getCount) + .containsExactly( + tuple("*-30.0", 1L), + tuple("30.0-50.0", 0L), + tuple("50.0-70.0", 0L), + tuple("70.0-80.0", 0L), + tuple("80.0-*", 2L)); + } + @Test public void default_sort_is_by_ascending_name() throws Exception { userSession.logIn(); diff --git a/server/sonar-server/src/test/java/org/sonar/server/measure/index/ProjectMeasuresIndexTest.java b/server/sonar-server/src/test/java/org/sonar/server/measure/index/ProjectMeasuresIndexTest.java index 87734139552..cc22b6b3d72 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/measure/index/ProjectMeasuresIndexTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/measure/index/ProjectMeasuresIndexTest.java @@ -79,6 +79,7 @@ public class ProjectMeasuresIndexTest { private static final String SECURITY_RATING = "security_rating"; private static final String NEW_SECURITY_RATING = "new_security_rating"; private static final String COVERAGE = "coverage"; + private static final String NEW_COVERAGE = "new_coverage"; private static final String DUPLICATION = "duplicated_lines_density"; private static final String NCLOC = "ncloc"; private static final String LANGUAGES = "languages"; @@ -634,6 +635,41 @@ public class ProjectMeasuresIndexTest { entry("80.0-*", 0L)); } + @Test + public void facet_new_coverage() { + index( + // 3 docs with coverage<30% + newDoc(NEW_COVERAGE, 0d), + newDoc(NEW_COVERAGE, 0d), + newDoc(NEW_COVERAGE, 29d), + // 2 docs with coverage>=30% and coverage<50% + newDoc(NEW_COVERAGE, 30d), + newDoc(NEW_COVERAGE, 49d), + // 4 docs with coverage>=50% and coverage<70% + newDoc(NEW_COVERAGE, 50d), + newDoc(NEW_COVERAGE, 60d), + newDoc(NEW_COVERAGE, 60d), + newDoc(NEW_COVERAGE, 69d), + // 2 docs with coverage>=70% and coverage<80% + newDoc(NEW_COVERAGE, 70d), + newDoc(NEW_COVERAGE, 79d), + // 5 docs with coverage>= 80% + newDoc(NEW_COVERAGE, 80d), + newDoc(NEW_COVERAGE, 80d), + newDoc(NEW_COVERAGE, 90d), + newDoc(NEW_COVERAGE, 90.5d), + newDoc(NEW_COVERAGE, 100d)); + + Facets facets = underTest.search(new ProjectMeasuresQuery(), new SearchOptions().addFacets(NEW_COVERAGE)).getFacets(); + + assertThat(facets.get(NEW_COVERAGE)).containsExactly( + entry("*-30.0", 3L), + entry("30.0-50.0", 2L), + entry("50.0-70.0", 4L), + entry("70.0-80.0", 2L), + entry("80.0-*", 5L)); + } + @Test public void facet_duplicated_lines_density() { index( -- 2.39.5