import org.sonar.core.util.logs.Profiler;
import org.sonar.server.platform.db.migration.MutableDatabaseMigrationState;
import org.sonar.server.platform.db.migration.history.MigrationHistory;
+import org.sonar.server.telemetry.TelemetryDbMigrationStepDurationProvider;
import org.sonar.server.telemetry.TelemetryDbMigrationSuccessProvider;
import org.sonar.server.telemetry.TelemetryDbMigrationStepsProvider;
import org.sonar.server.telemetry.TelemetryDbMigrationTotalTimeProvider;
private final TelemetryDbMigrationTotalTimeProvider telemetryDbMigrationTotalTimeProvider;
private final TelemetryDbMigrationStepsProvider telemetryDbMigrationStepsProvider;
private final TelemetryDbMigrationSuccessProvider telemetryDbMigrationSuccessProvider;
+ private final TelemetryDbMigrationStepDurationProvider telemetryDbMigrationStepDurationProvider;
public MigrationStepsExecutorImpl(Container migrationContainer, MigrationHistory migrationHistory, MutableDatabaseMigrationState databaseMigrationState,
TelemetryDbMigrationTotalTimeProvider telemetryDbMigrationTotalTimeProvider, TelemetryDbMigrationStepsProvider telemetryDbMigrationStepsProvider,
- TelemetryDbMigrationSuccessProvider telemetryDbMigrationSuccessProvider) {
+ TelemetryDbMigrationSuccessProvider telemetryDbMigrationSuccessProvider, TelemetryDbMigrationStepDurationProvider stepDurationProvider) {
this.migrationContainer = migrationContainer;
this.migrationHistory = migrationHistory;
this.databaseMigrationState = databaseMigrationState;
this.telemetryDbMigrationTotalTimeProvider = telemetryDbMigrationTotalTimeProvider;
this.telemetryDbMigrationStepsProvider = telemetryDbMigrationStepsProvider;
this.telemetryDbMigrationSuccessProvider = telemetryDbMigrationSuccessProvider;
+ this.telemetryDbMigrationStepDurationProvider = stepDurationProvider;
}
@Override
throw new MigrationStepExecutionException(step, e);
} finally {
if (done) {
- stepProfiler.stopInfo(STEP_STOP_PATTERN,
+ long durationInMiliseconds = stepProfiler.stopInfo(STEP_STOP_PATTERN,
databaseMigrationState.getCompletedMigrations() + 1,
databaseMigrationState.getTotalMigrations(),
step,
"success");
+ telemetryDbMigrationStepDurationProvider.addCompletedStep(step.getMigrationNumber(), durationInMiliseconds);
} else {
stepProfiler.stopError(STEP_STOP_PATTERN,
databaseMigrationState.getCompletedMigrations() + 1,
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2024 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.telemetry;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.sonar.telemetry.core.Dimension;
+import org.sonar.telemetry.core.Granularity;
+import org.sonar.telemetry.core.TelemetryDataProvider;
+import org.sonar.telemetry.core.TelemetryDataType;
+
+public class TelemetryDbMigrationStepDurationProvider implements TelemetryDataProvider<Long> {
+
+ private final Map<String, Long> dbMigrationStepDurations = new HashMap<>();
+
+ @Override
+ public String getMetricKey() {
+ return "db_migration_step_duration";
+ }
+
+ @Override
+ public Dimension getDimension() {
+ return Dimension.INSTALLATION;
+ }
+
+ @Override
+ public Granularity getGranularity() {
+ return Granularity.ADHOC;
+ }
+
+ @Override
+ public TelemetryDataType getType() {
+ return TelemetryDataType.INTEGER;
+ }
+
+ @Override
+ public Map<String, Long> getValues() {
+ return dbMigrationStepDurations;
+ }
+
+ @Override
+ public void after() {
+ dbMigrationStepDurations.clear();
+ }
+
+ public void addCompletedStep(Long migrationId, Long duration) {
+ dbMigrationStepDurations.put(migrationId.toString(), duration);
+ }
+}
import org.sonar.server.platform.db.migration.step.MigrationSteps;
import org.sonar.server.platform.db.migration.step.MigrationStepsExecutorImpl;
import org.sonar.server.platform.db.migration.step.RegisteredMigrationStep;
+import org.sonar.server.telemetry.TelemetryDbMigrationStepDurationProvider;
import org.sonar.server.telemetry.TelemetryDbMigrationSuccessProvider;
import org.sonar.server.telemetry.TelemetryDbMigrationStepsProvider;
import org.sonar.server.telemetry.TelemetryDbMigrationTotalTimeProvider;
migrationContainer.add(mock(TelemetryDbMigrationStepsProvider.class));
migrationContainer.add(mock(TelemetryDbMigrationTotalTimeProvider.class));
migrationContainer.add(mock(TelemetryDbMigrationSuccessProvider.class));
+ migrationContainer.add(mock(TelemetryDbMigrationStepDurationProvider.class));
migrationContainer.startComponents();
underTest.populateContainer(migrationContainer);
import org.sonar.server.platform.db.migration.step.MigrationSteps;
import org.sonar.server.platform.db.migration.step.NoOpMigrationStatusListener;
import org.sonar.server.platform.db.migration.step.RegisteredMigrationStep;
+import org.sonar.server.telemetry.TelemetryDbMigrationStepDurationProvider;
import org.sonar.server.telemetry.TelemetryDbMigrationSuccessProvider;
import org.sonar.server.telemetry.TelemetryDbMigrationStepsProvider;
import org.sonar.server.telemetry.TelemetryDbMigrationTotalTimeProvider;
private final TelemetryDbMigrationTotalTimeProvider telemetryDbMigrationTotalTimeProvider = new TelemetryDbMigrationTotalTimeProvider();
private final TelemetryDbMigrationStepsProvider telemetryUpgradeStepsProvider = new TelemetryDbMigrationStepsProvider();
private final TelemetryDbMigrationSuccessProvider telemetryDbMigrationSuccessProvider = new TelemetryDbMigrationSuccessProvider();
+ private final TelemetryDbMigrationStepDurationProvider telemetryDbMigrationStepDurationProvider = new TelemetryDbMigrationStepDurationProvider();
private final MigrationEngineImpl underTest = new MigrationEngineImpl(migrationHistory, serverContainer, migrationSteps);
@BeforeEach
serverContainer.add(migrationHistory);
serverContainer.add(stepRegistry);
serverContainer.add(databaseMigrationState);
+ serverContainer.add(telemetryDbMigrationStepDurationProvider);
serverContainer.startComponents();
}
private record TestMigrationStep(StepRegistry registry) implements MigrationStep {
@Override
- public void execute() throws SQLException {
+ public void execute() {
registry.stepRan = true;
}
}
import org.sonar.server.platform.db.migration.engine.MigrationContainer;
import org.sonar.server.platform.db.migration.engine.SimpleMigrationContainer;
import org.sonar.server.platform.db.migration.history.MigrationHistory;
+import org.sonar.server.telemetry.TelemetryDbMigrationStepDurationProvider;
import org.sonar.server.telemetry.TelemetryDbMigrationSuccessProvider;
import org.sonar.server.telemetry.TelemetryDbMigrationStepsProvider;
import org.sonar.server.telemetry.TelemetryDbMigrationTotalTimeProvider;
private final TelemetryDbMigrationTotalTimeProvider telemetryDbMigrationTotalTimeProvider = new TelemetryDbMigrationTotalTimeProvider();
private final TelemetryDbMigrationStepsProvider telemetryDbMigrationStepsProvider = new TelemetryDbMigrationStepsProvider();
private final TelemetryDbMigrationSuccessProvider telemetryDbMigrationSuccessProvider = new TelemetryDbMigrationSuccessProvider();
+ private final TelemetryDbMigrationStepDurationProvider telemetryDbMigrationStepDurationProvider = new TelemetryDbMigrationStepDurationProvider();
private final MigrationStepsExecutorImpl underTest = new MigrationStepsExecutorImpl(migrationContainer, migrationHistory, databaseMigrationState,
- telemetryDbMigrationTotalTimeProvider, telemetryDbMigrationStepsProvider, telemetryDbMigrationSuccessProvider);
+ telemetryDbMigrationTotalTimeProvider, telemetryDbMigrationStepsProvider, telemetryDbMigrationSuccessProvider, telemetryDbMigrationStepDurationProvider);
private final NoOpMigrationStatusListener migrationStatusListener = mock();
@BeforeEach
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2024 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.telemetry;
+
+import java.util.Map;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.telemetry.core.Dimension.INSTALLATION;
+import static org.sonar.telemetry.core.Granularity.ADHOC;
+import static org.sonar.telemetry.core.TelemetryDataType.INTEGER;
+
+class TelemetryDbMigrationStepDurationProviderTest {
+
+ @Test
+ void testGetters() {
+ TelemetryDbMigrationStepDurationProvider underTest = new TelemetryDbMigrationStepDurationProvider();
+
+ underTest.addCompletedStep(1L, 10L);
+ underTest.addCompletedStep(9L, 20L);
+
+ assertThat(underTest.getMetricKey()).isEqualTo("db_migration_step_duration");
+ assertThat(underTest.getGranularity()).isEqualTo(ADHOC);
+ assertThat(underTest.getDimension()).isEqualTo(INSTALLATION);
+ assertThat(underTest.getType()).isEqualTo(INTEGER);
+ assertThat(underTest.getValue()).isEmpty();
+ assertThat(underTest.getValues()).containsExactlyInAnyOrderEntriesOf(Map.of("1", 10L, "9", 20L));
+
+ underTest.after();
+
+ assertThat(underTest.getValues()).isEmpty();
+ }
+}
/**
* The implementation of this method might often need to make a call to a database.
- * For each metric either this method or {@link TelemetryDataProvider#getUuidValues()} should be implemented and used. Not both at once.
+ * For each metric either this method or {@link TelemetryDataProvider#getValues()} should be used. Not both at once.
*
* @return the value of the data provided by this instance.
*/
default Optional<T> getValue() {
- throw new IllegalStateException("Not implemented");
+ return Optional.empty();
}
/**
* The implementation of this method might often need to make a call to a database.
- * Similiar as {@link TelemetryDataProvider#getValue()} this method returns values of the metric. Some of the metrics
- * associate a UUID with a value. This method is used to return all the values associated with the UUIDs.
+ * Similar as {@link TelemetryDataProvider#getValue()} this method returns values of the metric. Some of the metrics
+ * associate a key with a value. This method is used to return all the values associated with the keys.
*
- * @return map of UUIDs and their values.
+ * @return map of keys and their values.
*/
- default Map<String, T> getUuidValues() {
- throw new IllegalStateException("Not implemented");
+ default Map<String, T> getValues() {
+ return Map.of();
}
/**
}
@Override
- public Map<String, T> getUuidValues() {
+ public Map<String, T> getValues() {
return Stream.of(keys)
.collect(Collectors.toMap(
key -> key,
private static Set<Metric> mapInstallationMetric(TelemetryDataProvider<?> provider) {
Optional<?> optionalValue = provider.getValue();
- if (provider.getGranularity() == Granularity.ADHOC && optionalValue.isEmpty()) {
+
+ Granularity granularity = provider.getGranularity();
+
+ if (granularity == Granularity.ADHOC && !provider.getValues().isEmpty()) {
+ return provider.getValues().entrySet().stream()
+ .map(entry -> new InstallationMetric(
+ provider.getMetricKey() + "." + entry.getKey(),
+ entry.getValue(),
+ provider.getType(),
+ granularity
+ )).collect(Collectors.toSet());
+ }
+
+ if (granularity == Granularity.ADHOC && optionalValue.isEmpty()) {
return Collections.emptySet();
}
provider.getMetricKey(),
optionalValue.orElse(null),
provider.getType(),
- provider.getGranularity()
+ granularity
));
}
private static Set<Metric> mapUserMetric(TelemetryDataProvider<?> provider) {
- return provider.getUuidValues().entrySet().stream()
+ return provider.getValues().entrySet().stream()
.map(entry -> new UserMetric(
provider.getMetricKey(),
entry.getValue(),
}
private static Set<Metric> mapProjectMetric(TelemetryDataProvider<?> provider) {
- return provider.getUuidValues().entrySet().stream()
+ return provider.getValues().entrySet().stream()
.map(entry -> new ProjectMetric(
provider.getMetricKey(),
entry.getValue(),
}
private static Set<Metric> mapLanguageMetric(TelemetryDataProvider<?> provider) {
- return provider.getUuidValues().entrySet().stream()
+ return provider.getValues().entrySet().stream()
.map(entry -> new LanguageMetric(
provider.getMetricKey(),
entry.getValue(),
);
}
+ @Test
+ void mapFromDataProvider_whenInstallationProviderWithMultiValue() {
+ TelemetryDataProvider<String> provider = new TestTelemetryBean(Dimension.INSTALLATION) {
+ @Override
+ public Granularity getGranularity() {
+ return Granularity.ADHOC;
+ }
+ };
+
+ Set<Metric> metrics = TelemetryMetricsMapper.mapFromDataProvider(provider);
+ List<InstallationMetric> userMetrics = retrieveList(metrics);
+
+ assertThat(userMetrics)
+ .extracting(InstallationMetric::getKey, InstallationMetric::getType, InstallationMetric::getValue, InstallationMetric::getGranularity)
+ .containsExactlyInAnyOrder(
+ tuple("telemetry-bean-a.key-1", TelemetryDataType.STRING, "value-1", Granularity.ADHOC),
+ tuple("telemetry-bean-a.key-2", TelemetryDataType.STRING, "value-2", Granularity.ADHOC)
+ );
+ }
+
@Test
void mapFromDataProvider_whenUserProvider() {
TelemetryDataProvider<String> provider = new TestTelemetryBean(Dimension.USER);
}
@Override
- public Map<String, String> getUuidValues() {
+ public Map<String, String> getValues() {
return METRIC_UUID_VALUES;
}
ProjectCppAutoconfigTelemetryProvider underTest = new ProjectCppAutoconfigTelemetryProvider(db.getDbClient());
@Test
- void getUuidValues_whenNoProjects_returnEmptyList() {
- assertThat(underTest.getUuidValues()).isEmpty();
+ void getValues_whenNoProjects_returnEmptyList() {
+ assertThat(underTest.getValues()).isEmpty();
}
@Test
- void getUuidValues_whenNoCppAndCProjects_returnEmptyMap() {
+ void getValues_whenNoCppAndCProjects_returnEmptyMap() {
Consumer<MetricDto> configureMetric = metric -> metric
.setValueType(STRING.name())
.setKey(NCLOC_LANGUAGE_DISTRIBUTION_KEY);
insertLiveMeasure("cobol", metric).accept(project2);
- assertThat(underTest.getUuidValues()).isEmpty();
+ assertThat(underTest.getValues()).isEmpty();
}
@Test
- void getUuidValues_when1CppAnd1CProject_returnMapWithSize2AndAutoconfigByDefault() {
+ void getValues_when1CppAnd1CProject_returnMapWithSize2AndAutoconfigByDefault() {
Consumer<MetricDto> configureMetric = metric -> metric
.setValueType(STRING.name())
.setKey(NCLOC_LANGUAGE_DISTRIBUTION_KEY);
insertLiveMeasure("java", metric).accept(project3);
insertLiveMeasure("cobol", metric).accept(project4);
- Map<String, String> actualResult = underTest.getUuidValues();
+ Map<String, String> actualResult = underTest.getValues();
assertThat(actualResult).hasSize(2)
.containsExactlyInAnyOrderEntriesOf(
}
@Test
- void getUuidValues_whenCAndCppProjectsWithDifferentConfig_returnMapWithSize2AndNotAutoconfig() {
+ void getValues_whenCAndCppProjectsWithDifferentConfig_returnMapWithSize2AndNotAutoconfig() {
Consumer<MetricDto> configureMetric = metric -> metric
.setValueType(STRING.name())
.setKey(NCLOC_LANGUAGE_DISTRIBUTION_KEY);
db.properties().insertProperty("sonar.cfamily.build-wrapper-output", "anyvalue", project1.getProjectDto().getUuid());
db.properties().insertProperty("sonar.cfamily.compile-commands", "anyvalue", project2.getProjectDto().getUuid());
- Map<String, String> actualResult = underTest.getUuidValues();
+ Map<String, String> actualResult = underTest.getValues();
assertThat(actualResult).hasSize(2)
.containsExactlyInAnyOrderEntriesOf(
}
@Test
- void getUuidValues_whenNoUsersInDatabase_shouldReturnEmptyMap() {
- Map<String, Boolean> uuidValues = underTest.getUuidValues();
+ void getValues_whenNoUsersInDatabase_shouldReturnEmptyMap() {
+ Map<String, Boolean> uuidValues = underTest.getValues();
assertThat(uuidValues).isEmpty();
}
@Test
- void getUuidValues_whenSomeUsersActive_shouldReturnBothBooleanValues() {
+ void getValues_whenSomeUsersActive_shouldReturnBothBooleanValues() {
db.users().insertUser(user -> user.setUuid("uuid1").setActive(true));
db.users().insertUser(user -> user.setUuid("uuid1").setActive(false));
db.getSession().commit();
- Map<String, Boolean> uuidValues = underTest.getUuidValues();
+ Map<String, Boolean> uuidValues = underTest.getValues();
assertThat(uuidValues).hasSize(2);
assertThat(uuidValues.values().stream().filter(Boolean::booleanValue)).hasSize(1);
}
@Test
- void getUuidValues_when10ActiveUsers_shouldReturn10BooleanValues() {
+ void getValues_when10ActiveUsers_shouldReturn10BooleanValues() {
for (int i = 0; i < 10; i++) {
db.users().insertUser(user -> user.setActive(true));
}
db.getSession().commit();
- Map<String, Boolean> uuidValues = underTest.getUuidValues();
+ Map<String, Boolean> uuidValues = underTest.getValues();
assertThat(uuidValues).hasSize(10);
assertThat(uuidValues.values().stream().filter(Boolean::booleanValue)).hasSize(10);
}
@Test
- void getUuidValues_shouldAnonymizeUserUuids() {
+ void getValues_shouldAnonymizeUserUuids() {
UserDto userDto1 = db.users().insertUser();
UserDto userDto2 = db.users().insertUser();
db.getSession().commit();
- Map<String, Boolean> uuidValues = underTest.getUuidValues();
+ Map<String, Boolean> uuidValues = underTest.getValues();
String anonymizedUser1 = DigestUtil.sha3_224Hex(userDto1.getUuid());
String anonymizedUser2 = DigestUtil.sha3_224Hex(userDto2.getUuid());
import org.sonar.server.platform.db.migration.MigrationConfigurationModule;
import org.sonar.server.platform.db.migration.charset.DatabaseCharsetChecker;
import org.sonar.server.platform.db.migration.version.DatabaseVersion;
+import org.sonar.server.telemetry.TelemetryDbMigrationStepDurationProvider;
import org.sonar.server.telemetry.TelemetryDbMigrationSuccessProvider;
import org.sonar.server.telemetry.TelemetryDbMigrationStepsProvider;
import org.sonar.server.telemetry.TelemetryDbMigrationTotalTimeProvider;
TelemetryDbMigrationTotalTimeProvider.class,
TelemetryDbMigrationStepsProvider.class,
TelemetryDbMigrationSuccessProvider.class,
+ TelemetryDbMigrationStepDurationProvider.class,
DatabaseMigrationStateImpl.class,
DatabaseMigrationExecutorServiceImpl.class);
}
@Override
- public Map<String, String> getUuidValues() {
+ public Map<String, String> getValues() {
Map<String, String> cppConfigTypePerProjectUuid = new HashMap<>();
try (DbSession dbSession = dbClient.openSession(true)) {
// In the future ideally languages should be defined in the codebase as enums, using strings is error-prone
}
@Override
- public Map<String, Long> getUuidValues() {
+ public Map<String, Long> getValues() {
try (DbSession dbSession = dbClient.openSession(false)) {
return getNclocDistribution(dbSession);
}
}
@Override
- public Map<String, Boolean> getUuidValues() {
+ public Map<String, Boolean> getValues() {
Map<String, Boolean> result = new HashMap<>();
int pageSize = 1000;
int page = 1;
import org.sonar.server.plugins.ServerPluginRepository;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.sonar.process.ProcessProperties.Property.PATH_DATA;
verify(container).add(ServerPluginRepository.class);
verify(container).add(DatabaseCharsetChecker.class);
- verify(container, times(24)).add(any());
+ verify(container, atLeastOnce()).add(any());
}
@Test
verify(container).add(ServerPluginRepository.class);
verify(container, never()).add(DatabaseCharsetChecker.class);
- verify(container, times(22)).add(any());
+ verify(container, atLeastOnce()).add(any());
}
import org.sonar.telemetry.core.TelemetryDataType;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assumptions.assumeFalse;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
assertEquals(Granularity.DAILY, telemetryVersionProvider.getGranularity());
assertEquals(TelemetryDataType.BOOLEAN, telemetryVersionProvider.getType());
assertEquals(Optional.of(expectedFipsEnabled), telemetryVersionProvider.getValue());
- assertThrows(IllegalStateException.class, telemetryVersionProvider::getUuidValues);
}
}
private final DbSession dbSession = mock(DbSession.class);
@Test
- void getUuidValues_returnsTheRightLanguageDistribution() {
+ void getValues_returnsTheRightLanguageDistribution() {
TelemetryNclocProvider telemetryNclocProvider = new TelemetryNclocProvider(dbClient);
when(dbClient.openSession(false)).thenReturn(dbSession);
assertEquals(Granularity.DAILY, telemetryNclocProvider.getGranularity());
assertEquals(Dimension.LANGUAGE, telemetryNclocProvider.getDimension());
- assertThat(telemetryNclocProvider.getUuidValues()).containsOnlyKeys("java", "xml", "csharp", "js");
- assertThat(telemetryNclocProvider.getUuidValues()).containsEntry("java", 22000L);
- assertThat(telemetryNclocProvider.getUuidValues()).containsEntry("xml", 1000L);
- assertThat(telemetryNclocProvider.getUuidValues()).containsEntry("csharp", 2000L);
- assertThat(telemetryNclocProvider.getUuidValues()).containsEntry("js", 1500L);
+ assertThat(telemetryNclocProvider.getValues()).containsOnlyKeys("java", "xml", "csharp", "js");
+ assertThat(telemetryNclocProvider.getValues()).containsEntry("java", 22000L);
+ assertThat(telemetryNclocProvider.getValues()).containsEntry("xml", 1000L);
+ assertThat(telemetryNclocProvider.getValues()).containsEntry("csharp", 2000L);
+ assertThat(telemetryNclocProvider.getValues()).containsEntry("js", 1500L);
}
}
\ No newline at end of file
import org.sonar.telemetry.core.TelemetryDataType;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
assertEquals(Granularity.DAILY, telemetryVersionProvider.getGranularity());
assertEquals(TelemetryDataType.STRING, telemetryVersionProvider.getType());
assertEquals(Optional.of("10.6"), telemetryVersionProvider.getValue());
- assertThrows(IllegalStateException.class, telemetryVersionProvider::getUuidValues);
}
}