diff options
author | Eric Giffon <eric.giffon@sonarsource.com> | 2024-09-03 12:04:04 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2024-10-09 20:02:46 +0000 |
commit | 0ff9b7313c17474a867f744aa63afd94795a134b (patch) | |
tree | 56a4e24870b95f2344a5655d8fe978801ec978ad /server/sonar-db-dao/src/test/java | |
parent | 75a2e6255fb114c56b0b3d1273ebec59c374714a (diff) | |
download | sonarqube-0ff9b7313c17474a867f744aa63afd94795a134b.tar.gz sonarqube-0ff9b7313c17474a867f744aa63afd94795a134b.zip |
SONAR-22872 Live update of JSON measures
Diffstat (limited to 'server/sonar-db-dao/src/test/java')
3 files changed, 250 insertions, 0 deletions
diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/measure/MeasureDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/measure/MeasureDaoTest.java index 1fdd6d7b9c1..a0786410bba 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/measure/MeasureDaoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/measure/MeasureDaoTest.java @@ -19,12 +19,24 @@ */ package org.sonar.db.measure; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import org.apache.commons.lang.math.RandomUtils; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.api.utils.System2; +import org.sonar.db.DbSession; import org.sonar.db.DbTester; +import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; +import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; +import static org.assertj.core.groups.Tuple.tuple; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verifyNoInteractions; import static org.sonar.db.measure.MeasureTesting.newMeasure; class MeasureDaoTest { @@ -58,6 +70,59 @@ class MeasureDaoTest { } @Test + void insertOrUpdate_inserts_or_updates_measure() { + // insert + MeasureDto dto = newMeasure(); + int count = underTest.insertOrUpdate(db.getSession(), dto); + assertThat(count).isEqualTo(1); + verifyTableSize(1); + verifyPersisted(dto); + + // update + String key = dto.getMetricValues().keySet().stream().findFirst().orElseThrow(); + dto.addValue(key, getDoubleValue()); + count = underTest.insertOrUpdate(db.getSession(), dto); + assertThat(count).isEqualTo(1); + verifyTableSize(1); + verifyPersisted(dto); + } + + @Test + void insertOrUpdate_merges_measures() { + // insert + Double value2 = getDoubleValue(); + MeasureDto dto = newMeasure(); + dto.getMetricValues().clear(); + dto.addValue("key1", getDoubleValue()) + .addValue("key2", value2); + int count = underTest.insert(db.getSession(), dto); + verifyPersisted(dto); + verifyTableSize(1); + assertThat(count).isEqualTo(1); + + // update key1 value, remove key2 (must not disappear from DB) and add key3 + Double value1 = getDoubleValue(); + Double value3 = getDoubleValue(); + dto.addValue("key1", value1) + .addValue("key3", value3) + .getMetricValues().remove("key2"); + count = underTest.insertOrUpdate(db.getSession(), dto); + assertThat(count).isEqualTo(1); + verifyTableSize(1); + + assertThat(underTest.selectMeasure(db.getSession(), dto.getComponentUuid())) + .hasValueSatisfying(selected -> { + assertThat(selected.getComponentUuid()).isEqualTo(dto.getComponentUuid()); + assertThat(selected.getBranchUuid()).isEqualTo(dto.getBranchUuid()); + assertThat(selected.getMetricValues()).contains( + entry("key1", value1), + entry("key2", value2), + entry("key3", value3)); + assertThat(selected.getJsonValueHash()).isEqualTo(dto.computeJsonValueHash()); + }); + } + + @Test void select_measure() { MeasureDto measure1 = newMeasure(); MeasureDto measure2 = newMeasure(); @@ -70,6 +135,126 @@ class MeasureDaoTest { } @Test + void selectMeasure_with_single_metric() { + String metricKey = "metric1"; + String value = "foo"; + MeasureDto measure1 = newMeasure().addValue(metricKey, value); + MeasureDto measure2 = newMeasure(); + underTest.insert(db.getSession(), measure1); + underTest.insert(db.getSession(), measure2); + + assertThat(underTest.selectMeasure(db.getSession(), measure1.getComponentUuid(), metricKey)) + .hasValueSatisfying(selected -> assertThat(selected.getMetricValues()).containsOnly(entry(metricKey, value))); + + assertThat(underTest.selectMeasure(db.getSession(), "unknown-component", metricKey)).isEmpty(); + } + + @Test + void selectByComponentUuidsAndMetricKeys_does_not_use_db_when_no_components() { + String metricKey = randomAlphabetic(7); + newMeasure().addValue(metricKey, randomAlphabetic(11)); + + DbSession dbSession = mock(DbSession.class); + assertThat(underTest.selectByComponentUuidsAndMetricKeys(dbSession, emptyList(), singletonList(metricKey))) + .isEmpty(); + verifyNoInteractions(dbSession); + } + + @Test + void selectByComponentUuidsAndMetricKeys_does_not_use_db_when_no_metrics() { + DbSession dbSession = mock(DbSession.class); + assertThat(underTest.selectByComponentUuidsAndMetricKeys(dbSession, singletonList("nonexistent"), emptyList())) + .isEmpty(); + verifyNoInteractions(dbSession); + } + + @Test + void selectByComponentUuidsAndMetricKeys_with_single_component_and_single_metric() { + String metricKey = randomAlphabetic(7); + String value = randomAlphabetic(11); + MeasureDto measure = newMeasure().addValue(metricKey, value); + underTest.insert(db.getSession(), measure); + + List<MeasureDto> measureDtos = underTest.selectByComponentUuidsAndMetricKeys( + db.getSession(), singletonList(measure.getComponentUuid()), singletonList(metricKey)); + assertThat(measureDtos).hasSize(1); + assertThat(measureDtos.get(0).getMetricValues()).isEqualTo(Map.of(metricKey, value)); + } + + @Test + void selectByComponentUuidsAndMetricKeys_with_nonexistent_component_returns_empty() { + String metricKey = randomAlphabetic(7); + String value = randomAlphabetic(11); + MeasureDto measure = newMeasure().addValue(metricKey, value); + underTest.insert(db.getSession(), measure); + + assertThat(underTest.selectByComponentUuidsAndMetricKeys( + db.getSession(), singletonList("nonexistent"), singletonList(metricKey))).isEmpty(); + + assertThat(underTest.selectByComponentUuidsAndMetricKeys( + db.getSession(), singletonList(measure.getComponentUuid()), singletonList(metricKey))).isNotEmpty(); + } + + @Test + void selectByComponentUuidsAndMetricKeys_with_nonexistent_metric_returns_empty() { + String metricKey = randomAlphabetic(7); + String value = randomAlphabetic(11); + MeasureDto measure = newMeasure().addValue(metricKey, value); + underTest.insert(db.getSession(), measure); + + assertThat(underTest.selectByComponentUuidsAndMetricKeys( + db.getSession(), singletonList(measure.getComponentUuid()), singletonList("nonexistent"))).isEmpty(); + + assertThat(underTest.selectByComponentUuidsAndMetricKeys( + db.getSession(), singletonList(measure.getComponentUuid()), singletonList(metricKey))).isNotEmpty(); + + MeasureDto m = newMeasure().addValue("foo", "bar"); + underTest.insert(db.getSession(), m); + } + + @Test + void selectByComponentUuidsAndMetricKeys_with_many_components_and_many_metrics() { + String metric1 = "metric1"; + String metric2 = "metric2"; + String nonRequestedMetric = "nonRequestedMetric"; + + String component1 = "component1"; + String component1measure1 = "component1measure1"; + underTest.insert(db.getSession(), + newMeasure().setComponentUuid(component1) + .addValue(metric1, component1measure1) + .addValue(nonRequestedMetric, randomAlphabetic(7))); + + String component2 = "component2"; + String component2measure1 = "component2measure1"; + String component2measure2 = "component2measure2"; + underTest.insert(db.getSession(), + newMeasure().setComponentUuid(component2) + .addValue(metric1, component2measure1) + .addValue(metric2, component2measure2) + .addValue(nonRequestedMetric, randomAlphabetic(7))); + + String nonRequestedComponent = "nonRequestedComponent"; + underTest.insert(db.getSession(), + newMeasure().setComponentUuid(nonRequestedComponent).addValue(metric1, randomAlphabetic(7))); + + List<MeasureDto> measureDtos = underTest.selectByComponentUuidsAndMetricKeys( + db.getSession(), Arrays.asList(component1, component2), Arrays.asList(metric1, metric2)); + + assertThat(measureDtos.stream().map(MeasureDto::getComponentUuid)) + .containsExactlyInAnyOrder(component1, component2); + + assertThat(measureDtos).flatExtracting(m -> m.getMetricValues().entrySet().stream() + .map(entry -> tuple(m.getComponentUuid(), entry.getKey(), entry.getValue())) + .toList()) + .containsExactlyInAnyOrder( + tuple(component1, metric1, component1measure1), + tuple(component2, metric1, component2measure1), + tuple(component2, metric2, component2measure2) + ); + } + + @Test void select_branch_measure_hashes() { MeasureDto measure1 = new MeasureDto() .setComponentUuid("c1") @@ -104,4 +289,8 @@ class MeasureDaoTest { assertThat(selected).usingRecursiveComparison().isEqualTo(dto); }); } + + private static double getDoubleValue() { + return RandomUtils.nextInt(100); + } } diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/measure/MeasureDtoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/measure/MeasureDtoTest.java index 9299402942d..7a582fc1320 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/measure/MeasureDtoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/measure/MeasureDtoTest.java @@ -19,14 +19,37 @@ */ package org.sonar.db.measure; +import java.util.List; import java.util.Map; import java.util.TreeMap; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic; import static org.assertj.core.api.Assertions.assertThat; class MeasureDtoTest { + @ParameterizedTest + @MethodSource("valuesOfDifferentTypes") + void getString_returns_string_value(Object value) { + String metricKey = randomAlphabetic(7); + MeasureDto measureDto = new MeasureDto().addValue(metricKey, value); + assertThat(measureDto.getString(metricKey)).isEqualTo(String.valueOf(value)); + } + + private static List<Object> valuesOfDifferentTypes() { + return List.of(2, 3.14, "foo"); + } + + @Test + void getString_returns_null_for_nonexistent_metric() { + String metricKey = randomAlphabetic(7); + MeasureDto measureDto = new MeasureDto(); + assertThat(measureDto.getString(metricKey)).isNull(); + } + @Test void compute_json_value_hash() { MeasureDto measureDto = new MeasureDto(); diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/metric/MetricDtoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/metric/MetricDtoTest.java index f010d0fe2dd..4dc04b7e57d 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/metric/MetricDtoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/metric/MetricDtoTest.java @@ -19,11 +19,27 @@ */ package org.sonar.db.metric; +import java.util.stream.Stream; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.sonar.api.measures.Metric; import static com.google.common.base.Strings.repeat; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.sonar.api.measures.Metric.ValueType.BOOL; +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.FLOAT; +import static org.sonar.api.measures.Metric.ValueType.INT; +import static org.sonar.api.measures.Metric.ValueType.LEVEL; +import static org.sonar.api.measures.Metric.ValueType.MILLISEC; +import static org.sonar.api.measures.Metric.ValueType.PERCENT; +import static org.sonar.api.measures.Metric.ValueType.RATING; +import static org.sonar.api.measures.Metric.ValueType.STRING; +import static org.sonar.api.measures.Metric.ValueType.WORK_DUR; class MetricDtoTest { @@ -98,4 +114,26 @@ class MetricDtoTest { .isInstanceOf(IllegalArgumentException.class) .hasMessage("Metric domain length (65) is longer than the maximum authorized (64). '" + a65 + "' was provided."); } + + @ParameterizedTest + @MethodSource("metric_types") + void isNumeric_returns_true_for_numeric_types(Metric.ValueType type, boolean expected) { + assertThat(underTest.setValueType(type.name()).isNumeric()).isEqualTo(expected); + } + + private static Stream<Arguments> metric_types() { + return Stream.of( + Arguments.of(INT, true), + Arguments.of(FLOAT, true), + Arguments.of(PERCENT, true), + Arguments.of(BOOL, true), + Arguments.of(STRING, false), + Arguments.of(MILLISEC, true), + Arguments.of(DATA, false), + Arguments.of(LEVEL, false), + Arguments.of(DISTRIB, false), + Arguments.of(RATING, true), + Arguments.of(WORK_DUR, true) + ); + } } |