aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-db-dao/src/test/java
diff options
context:
space:
mode:
authorEric Giffon <eric.giffon@sonarsource.com>2024-09-03 12:04:04 +0200
committersonartech <sonartech@sonarsource.com>2024-10-09 20:02:46 +0000
commit0ff9b7313c17474a867f744aa63afd94795a134b (patch)
tree56a4e24870b95f2344a5655d8fe978801ec978ad /server/sonar-db-dao/src/test/java
parent75a2e6255fb114c56b0b3d1273ebec59c374714a (diff)
downloadsonarqube-0ff9b7313c17474a867f744aa63afd94795a134b.tar.gz
sonarqube-0ff9b7313c17474a867f744aa63afd94795a134b.zip
SONAR-22872 Live update of JSON measures
Diffstat (limited to 'server/sonar-db-dao/src/test/java')
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/measure/MeasureDaoTest.java189
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/measure/MeasureDtoTest.java23
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/metric/MetricDtoTest.java38
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)
+ );
+ }
}