.map(BranchDto::isNeedIssueSync)
.orElse(false);
}
+
+ public List<BranchDto> selectAllBranches(DbSession dbSession) {
+ return mapper(dbSession).selectAllBranches();
+ }
}
Optional<BranchDto> selectMainBranchByProjectUuid(String projectUuid);
List<BranchDto> selectMainBranchesByProjectUuids(@Param("projectUuids") Collection<String> projectUuids);
+
+ List<BranchDto> selectAllBranches();
}
return session.getMapper(NewCodePeriodMapper.class);
}
+ public List<NewCodePeriodDto> selectAll(DbSession dbSession) {
+ return mapper(dbSession).selectAll();
+ }
}
long countByProjectAnalysis(String projectAnalysisUuid);
List<NewCodePeriodDto> selectAllByProject(String projectUuid);
+
+ List<NewCodePeriodDto> selectAll();
}
</foreach>
</select>
+ <select id="selectAllBranches" resultType="org.sonar.db.component.BranchDto">
+ select
+ <include refid="columns"/>
+ from project_branches pb
+ where branch_type='BRANCH'
+ </select>
+
<select id="selectByProjectUuid" parameterType="string" resultType="org.sonar.db.component.BranchDto">
select <include refid="columns"/>
from project_branches pb
pb.project_uuid = #{projectUuid, jdbcType=VARCHAR}
</select>
+
<select id="selectMainBranchByProjectUuid" resultType="org.sonar.db.component.BranchDto">
select <include refid="columns"/>
from project_branches pb
AND ncp.branch_uuid is null
</select>
+ <select id="selectAll" parameterType="map" resultType="org.sonar.db.newcodeperiod.NewCodePeriodDto">
+ SELECT
+ <include refid="newCodePeriodMapperColumns"/>
+ FROM new_code_periods ncp
+ </select>
+
<select id="selectAllByProject" parameterType="map" resultType="org.sonar.db.newcodeperiod.NewCodePeriodDto">
SELECT
<include refid="newCodePeriodMapperColumns"/>
package org.sonar.server.telemetry;
import java.util.Arrays;
+import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.sonar.db.user.UserTelemetryDto;
import static java.util.Objects.requireNonNullElse;
+import static org.sonar.db.newcodeperiod.NewCodePeriodType.PREVIOUS_VERSION;
public class TelemetryData {
private final String serverId;
private final List<UserTelemetryDto> users;
private final List<Project> projects;
private final List<ProjectStatistics> projectStatistics;
+ private final List<Branch> branches;
private final List<QualityGate> qualityGates;
+ private final Collection<NewCodeDefinition> newCodeDefinitions;
private final Boolean hasUnanalyzedC;
private final Boolean hasUnanalyzedCpp;
+ private final int ncdId;
private final Set<String> customSecurityConfigs;
private TelemetryData(Builder builder) {
hasUnanalyzedCpp = builder.hasUnanalyzedCpp;
customSecurityConfigs = requireNonNullElse(builder.customSecurityConfigs, Set.of());
managedInstanceInformation = builder.managedInstanceInformation;
+ ncdId = builder.ncdId;
+ branches = builder.branches;
+ newCodeDefinitions = builder.newCodeDefinitions;
}
public String getServerId() {
return new Builder();
}
+ public int getNcdId() {
+ return ncdId;
+ }
+
+ public List<Branch> getBranches() {
+ return branches;
+ }
+
+ public Collection<NewCodeDefinition> getNewCodeDefinitions() {
+ return newCodeDefinitions;
+ }
+
static class Builder {
private String serverId;
private String version;
private List<UserTelemetryDto> users;
private List<Project> projects;
private List<ProjectStatistics> projectStatistics;
+ private List<Branch> branches;
+ private Collection<NewCodeDefinition> newCodeDefinitions;
private List<QualityGate> qualityGates;
+ private int ncdId;
private Builder() {
// enforce static factory method
return this;
}
+ Builder setNcdId(int ncdId) {
+ this.ncdId = ncdId;
+ return this;
+ }
+
private static void requireNonNullValues(Object... values) {
Arrays.stream(values).forEach(Objects::requireNonNull);
}
+ Builder setBranches(List<Branch> branches) {
+ this.branches = branches;
+ return this;
+ }
+
+ Builder setNewCodeDefinitions(Collection<NewCodeDefinition> newCodeDefinitions) {
+ this.newCodeDefinitions = newCodeDefinitions;
+ return this;
+ }
}
record Database(String name, String version) {
}
+ record NewCodeDefinition(String type, @Nullable String value, String scope) {
+
+ private static final NewCodeDefinition instanceDefault = new NewCodeDefinition(PREVIOUS_VERSION.name(), "", "instance");
+
+ public static NewCodeDefinition getInstanceDefault() {
+ return instanceDefault;
+ }
+
+ @Override
+ public String value() {
+ return value == null ? "" : value;
+ }
+ }
+
+ record Branch(String projectUuid, String branchUuid, int ncdId) {
+ }
+
record Project(String projectUuid, Long lastAnalysis, String language, Long loc) {
}
private final Long technicalDebt;
private final Long developmentCost;
+ private final int ncdId;
+
ProjectStatistics(Builder builder) {
this.projectUuid = builder.projectUuid;
this.branchCount = builder.branchCount;
this.securityHotspots = builder.securityHotspots;
this.technicalDebt = builder.technicalDebt;
this.developmentCost = builder.developmentCost;
+ this.ncdId = builder.ncdId;
+ }
+
+ public int getNcdId() {
+ return ncdId;
}
public String getProjectUuid() {
private Long securityHotspots;
private Long technicalDebt;
private Long developmentCost;
+ private int ncdId;
public Builder setProjectUuid(String projectUuid) {
this.projectUuid = projectUuid;
return this;
}
+ public Builder setNcdId(int ncdId) {
+ this.ncdId = ncdId;
+ return this;
+ }
+
public Builder setBranchCount(Long branchCount) {
this.branchCount = branchCount;
return this;
private static final String LANGUAGE_PROPERTY = "language";
private static final String VERSION = "version";
+ private static final String NCD_ID = "ncdId";
+ private static final String PROJECT_ID = "projectUuid";
private final List<TelemetryExtension> extensions;
json.prop(VERSION, telemetryData.getVersion());
json.prop("messageSequenceNumber", telemetryData.getMessageSequenceNumber());
json.prop("localTimestamp", toUtc(system2.now()));
+ json.prop(NCD_ID, telemetryData.getNcdId());
telemetryData.getEdition().ifPresent(e -> json.prop("edition", e.name().toLowerCase(Locale.ENGLISH)));
json.prop("defaultQualityGate", telemetryData.getDefaultQualityGate());
json.name("database");
writeUserData(json, telemetryData);
writeProjectData(json, telemetryData);
writeProjectStatsData(json, telemetryData);
+ writeBranches(json, telemetryData);
+ writeNewCodeDefinitions(json, telemetryData);
writeQualityGates(json, telemetryData);
writeManagedInstanceInformation(json, telemetryData.getManagedInstanceInformation());
extensions.forEach(e -> e.write(json));
json.beginArray();
telemetryData.getProjects().forEach(project -> {
json.beginObject();
- json.prop("projectUuid", project.projectUuid());
+ json.prop(PROJECT_ID, project.projectUuid());
if (project.lastAnalysis() != null) {
json.prop("lastAnalysis", toUtc(project.lastAnalysis()));
}
}
}
+ private static void writeBranches(JsonWriter json, TelemetryData telemetryData) {
+ if (telemetryData.getBranches() != null) {
+ json.name("branches");
+ json.beginArray();
+ telemetryData.getBranches().forEach(branch -> {
+ json.beginObject();
+ json.prop(PROJECT_ID, branch.projectUuid());
+ json.prop("branchUuid", branch.branchUuid());
+ json.prop(NCD_ID, branch.ncdId());
+ json.endObject();
+ });
+ json.endArray();
+ }
+ }
+
+ private static void writeNewCodeDefinitions(JsonWriter json, TelemetryData telemetryData) {
+ if (telemetryData.getNewCodeDefinitions() != null) {
+ json.name("new-code-definitions");
+ json.beginArray();
+ telemetryData.getNewCodeDefinitions().forEach(ncd -> {
+ json.beginObject();
+ json.prop(NCD_ID, ncd.hashCode());
+ json.prop("type", ncd.type());
+ json.prop("value", ncd.value());
+ json.prop("scope", ncd.scope());
+ json.endObject();
+ });
+ json.endArray();
+ }
+ }
+
private static void writeProjectStatsData(JsonWriter json, TelemetryData telemetryData) {
if (telemetryData.getProjectStatistics() != null) {
json.name("projects-general-stats");
json.beginArray();
telemetryData.getProjectStatistics().forEach(project -> {
json.beginObject();
- json.prop("projectUuid", project.getProjectUuid());
+ json.prop(PROJECT_ID, project.getProjectUuid());
json.prop("branchCount", project.getBranchCount());
json.prop("pullRequestCount", project.getPullRequestCount());
json.prop("qualityGate", project.getQualityGate());
json.prop("scm", project.getScm());
json.prop("ci", project.getCi());
json.prop("devopsPlatform", project.getDevopsPlatform());
+ json.prop(NCD_ID, project.getNcdId());
project.getBugs().ifPresent(bugs -> json.prop("bugs", bugs));
project.getVulnerabilities().ifPresent(vulnerabilities -> json.prop("vulnerabilities", vulnerabilities));
project.getSecurityHotspots().ifPresent(securityHotspots -> json.prop("securityHotspots", securityHotspots));
TelemetryData load();
String loadServerId();
+
+ void reset();
}
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+import static org.sonar.db.newcodeperiod.NewCodePeriodType.NUMBER_OF_DAYS;
+import static org.sonar.db.newcodeperiod.NewCodePeriodType.PREVIOUS_VERSION;
import static org.sonar.test.JsonAssert.assertJson;
@RunWith(DataProviderRunner.class)
private final TelemetryDataJsonWriter underTest = new TelemetryDataJsonWriter(List.of(extension), system2);
+ private static final int NCD_ID = 12345;
+
+ private static final TelemetryData.NewCodeDefinition NCD_INSTANCE =
+ new TelemetryData.NewCodeDefinition(PREVIOUS_VERSION.name(), "", "instance");
+ private static final TelemetryData.NewCodeDefinition NCD_PROJECT =
+ new TelemetryData.NewCodeDefinition(NUMBER_OF_DAYS.name(), "30", "project");
+
@Test
public void write_server_id_version_and_sequence() {
TelemetryData data = telemetryBuilder().build();
"vulnerabilities": 3,
"securityHotspots": 4,
"technicalDebt": 60,
- "developmentCost": 30
+ "developmentCost": 30,
+ "ncdId": 12345
},
{
"projectUuid": "uuid-1",
"vulnerabilities": 6,
"securityHotspots": 8,
"technicalDebt": 120,
- "developmentCost": 60
+ "developmentCost": 60,
+ "ncdId": 12345
},
{
"projectUuid": "uuid-2",
"vulnerabilities": 9,
"securityHotspots": 12,
"technicalDebt": 180,
- "developmentCost": 90
+ "developmentCost": 90,
+ "ncdId": 12345
}
]
}
);
}
+ @Test
+ public void writes_all_branches() {
+ TelemetryData data = telemetryBuilder()
+ .setBranches(attachBranches())
+ .build();
+
+ String json = writeTelemetryData(data);
+ assertJson(json).isSimilarTo("""
+ {
+ "branches": [
+ {
+ "projectUuid": "%s",
+ "branchUuid": "%s",
+ "ncdId": %s
+ },
+ {
+ "projectUuid": "%s",
+ "branchUuid": "%s",
+ "ncdId": %s
+ },
+ ]
+
+ }
+ """.formatted("projectUuid1", "branchUuid1", NCD_ID, "projectUuid2", "branchUuid2", NCD_ID));
+ }
+
+ @Test
+ public void writes_new_code_definitions() {
+ TelemetryData data = telemetryBuilder()
+ .setNewCodeDefinitions(attachNewCodeDefinitions())
+ .build();
+
+ String json = writeTelemetryData(data);
+ assertJson(json).isSimilarTo("""
+ {
+ "new-code-definitions": [
+ {
+ "ncdId": %s,
+ "type": "%s",
+ "value": "%s",
+ "scope": "%s"
+ },
+ {
+ "ncdId": %s,
+ "type": "%s",
+ "value": "%s",
+ "scope": "%s"
+ },
+ ]
+
+ }
+ """.formatted(NCD_INSTANCE.hashCode(), NCD_INSTANCE.type(), NCD_INSTANCE.value(), NCD_INSTANCE.scope(), NCD_PROJECT.hashCode(),
+ NCD_PROJECT.type(), NCD_PROJECT.value(), NCD_PROJECT.scope()));
+ }
+
+ @Test
+ public void writes_instance_new_code_definition() {
+ TelemetryData data = telemetryBuilder().build();
+
+ String json = writeTelemetryData(data);
+ assertThat(json).contains("ncdId");
+
+ }
+
private static TelemetryData.Builder telemetryBuilder() {
return TelemetryData.builder()
.setServerId("foo")
.setMessageSequenceNumber(1L)
.setPlugins(Collections.emptyMap())
.setManagedInstanceInformation(new TelemetryData.ManagedInstanceInformation(false, null))
- .setDatabase(new TelemetryData.Database("H2", "11"));
+ .setDatabase(new TelemetryData.Database("H2", "11"))
+ .setNcdId(NCD_ID);
}
@NotNull
.setPRCount((i + 1L) * 2L)
.setQG("qg-" + i).setCi("ci-" + i)
.setScm("scm-" + i)
- .setDevops("devops-" + i);
+ .setDevops("devops-" + i)
+ .setNcdId(NCD_ID);
}
private static TelemetryData.ProjectStatistics.Builder getProjectStatisticsWithMetricBuilder(int i) {
new TelemetryData.QualityGate("uuid-2", "over-compliant"));
}
+ private List<TelemetryData.Branch> attachBranches() {
+ return List.of(new TelemetryData.Branch("projectUuid1", "branchUuid1", NCD_ID),
+ new TelemetryData.Branch("projectUuid2", "branchUuid2", NCD_ID));
+ }
+ private List<TelemetryData.NewCodeDefinition> attachNewCodeDefinitions() {
+ return List.of(NCD_INSTANCE, NCD_PROJECT);
+ }
+
@DataProvider
public static Object[][] allEditions() {
return Arrays.stream(EditionProvider.Edition.values())
dataJsonWriter.writeTelemetryData(json, statistics);
}
telemetryClient.upload(jsonString.toString());
+ dataLoader.reset();
}
private boolean shouldUploadStatistics(long now) {
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
+import javax.annotation.Nullable;
import javax.inject.Inject;
import org.sonar.api.config.Configuration;
import org.sonar.api.platform.Server;
import org.sonar.db.alm.setting.ALM;
import org.sonar.db.alm.setting.ProjectAlmKeyAndProject;
import org.sonar.db.component.AnalysisPropertyValuePerProject;
+import org.sonar.db.component.BranchDto;
import org.sonar.db.component.PrBranchAnalyzedLanguageCountByProjectDto;
import org.sonar.db.component.SnapshotDto;
import org.sonar.db.measure.LiveMeasureDto;
import org.sonar.db.measure.ProjectLocDistributionDto;
import org.sonar.db.metric.MetricDto;
+import org.sonar.db.newcodeperiod.NewCodePeriodDto;
import org.sonar.db.qualitygate.ProjectQgateAssociationDto;
import org.sonar.db.qualitygate.QualityGateDto;
import org.sonar.server.management.ManagedInstanceService;
import org.sonar.server.qualitygate.QualityGateCaycChecker;
import org.sonar.server.qualitygate.QualityGateFinder;
import org.sonar.server.telemetry.TelemetryData.Database;
+import org.sonar.server.telemetry.TelemetryData.NewCodeDefinition;
import static java.util.Arrays.asList;
import static java.util.Optional.ofNullable;
import static org.sonar.core.platform.EditionProvider.Edition.COMMUNITY;
import static org.sonar.core.platform.EditionProvider.Edition.DATACENTER;
import static org.sonar.core.platform.EditionProvider.Edition.ENTERPRISE;
+import static org.sonar.db.newcodeperiod.NewCodePeriodType.REFERENCE_BRANCH;
import static org.sonar.server.metric.UnanalyzedLanguageMetrics.UNANALYZED_CPP_KEY;
import static org.sonar.server.metric.UnanalyzedLanguageMetrics.UNANALYZED_C_KEY;
import static org.sonar.server.telemetry.TelemetryDaemon.I_PROP_MESSAGE_SEQUENCE;
private final QualityGateCaycChecker qualityGateCaycChecker;
private final QualityGateFinder qualityGateFinder;
private final ManagedInstanceService managedInstanceService;
+ private final Set<NewCodeDefinition> newCodeDefinitions = new HashSet<>();
+ private final Map<String, NewCodeDefinition> ncdByProject = new HashMap<>();
+ private final Map<String, NewCodeDefinition> ncdByBranch = new HashMap<>();
+ private NewCodeDefinition instanceNcd = NewCodeDefinition.getInstanceDefault();
@Inject
public TelemetryDataLoaderImpl(Server server, DbClient dbClient, PluginRepository pluginRepository,
getVersion));
data.setPlugins(plugins);
try (DbSession dbSession = dbClient.openSession(false)) {
+ var branchDtos = dbClient.branchDao().selectAllBranches(dbSession);
+ loadNewCodeDefinitions(dbSession, branchDtos);
+
data.setDatabase(loadDatabaseMetadata(dbSession));
+ data.setNcdId(instanceNcd.hashCode());
+ data.setNewCodeDefinitions(newCodeDefinitions);
String defaultQualityGateUuid = qualityGateFinder.getDefault(dbSession).getUuid();
resolveUnanalyzedLanguageCode(data, dbSession);
resolveProjectStatistics(data, dbSession, defaultQualityGateUuid);
resolveProjects(data, dbSession);
+ resolveBranches(data, branchDtos);
resolveQualityGates(data, dbSession);
resolveUsers(data, dbSession);
}
installationDateProperty.ifPresent(s -> data.setInstallationDate(Long.valueOf(s)));
Optional<String> installationVersionProperty = internalProperties.read(InternalProperties.INSTALLATION_VERSION);
-
return data
.setInstallationVersion(installationVersionProperty.orElse(null))
.setInDocker(dockerSupport.isRunningInDocker())
.build();
}
+ private void resolveBranches(TelemetryData.Builder data, List<BranchDto> branchDtos) {
+ var branches = branchDtos.stream()
+ .map(dto -> {
+ var projectNcd = ncdByProject.getOrDefault(dto.getProjectUuid(), instanceNcd);
+ var ncdId = ncdByBranch.getOrDefault(dto.getUuid(), projectNcd).hashCode();
+ return new TelemetryData.Branch(dto.getProjectUuid(), dto.getUuid(), ncdId);
+ })
+ .toList();
+ data.setBranches(branches);
+ }
+
+ @Override
+ public void reset() {
+ this.newCodeDefinitions.clear();
+ this.ncdByBranch.clear();
+ this.ncdByProject.clear();
+ this.instanceNcd = NewCodeDefinition.getInstanceDefault();
+ }
+
+ private void loadNewCodeDefinitions(DbSession dbSession, List<BranchDto> branchDtos) {
+ var branchUuidByKey = branchDtos.stream().collect(Collectors.toMap(dto -> createBranchUniqueKey(dto.getProjectUuid(), dto.getBranchKey()), BranchDto::getUuid));
+ List<NewCodePeriodDto> newCodePeriodDtos = dbClient.newCodePeriodDao().selectAll(dbSession);
+ NewCodeDefinition ncd;
+ boolean hasInstance = false;
+ for (var dto : newCodePeriodDtos) {
+ String projectUuid = dto.getProjectUuid();
+ String branchUuid = dto.getBranchUuid();
+ if (branchUuid == null && projectUuid == null) {
+ ncd = new NewCodeDefinition(dto.getType().name(), dto.getValue(), "instance");
+ this.instanceNcd = ncd;
+ hasInstance = true;
+ } else if (projectUuid != null) {
+ var value = dto.getType() == REFERENCE_BRANCH ? branchUuidByKey.get(createBranchUniqueKey(projectUuid, dto.getValue())) : dto.getValue();
+ if (branchUuid == null) {
+ ncd = new NewCodeDefinition(dto.getType().name(), value, "project");
+ this.ncdByProject.put(projectUuid, ncd);
+ } else {
+ ncd = new NewCodeDefinition(dto.getType().name(), value, "branch");
+ this.ncdByBranch.put(branchUuid, ncd);
+ }
+ } else {
+ throw new IllegalStateException(String.format("Error in loading telemetry data. New code definition for branch %s doesn't have a projectUuid", branchUuid));
+ }
+ this.newCodeDefinitions.add(ncd);
+ }
+ if (!hasInstance) {
+ this.newCodeDefinitions.add(NewCodeDefinition.getInstanceDefault());
+ }
+ }
+
+ private static String createBranchUniqueKey(String projectUuid, @Nullable String branchKey) {
+ return projectUuid + "-" + branchKey;
+ }
private void resolveUnanalyzedLanguageCode(TelemetryData.Builder data, DbSession dbSession) {
long numberOfUnanalyzedCMeasures = dbClient.liveMeasureDao().countProjectsHavingMeasure(dbSession, UNANALYZED_C_KEY);
.setVulnerabilities(metrics.getOrDefault("vulnerabilities", null))
.setSecurityHotspots(metrics.getOrDefault("security_hotspots", null))
.setTechnicalDebt(metrics.getOrDefault("sqale_index", null))
+ .setNcdId(ncdByProject.getOrDefault(projectUuid, instanceNcd).hashCode())
.build();
projectStatistics.add(stats);
}
return configuration.get(property).isPresent();
}
- private boolean isScimEnabled() {
- return this.internalProperties.read(SCIM_PROPERTY_ENABLED).map(Boolean::parseBoolean).orElse(false);
- }
private TelemetryData.ManagedInstanceInformation buildManagedInstanceInformation() {
String provider = managedInstanceService.isInstanceExternallyManaged() ? managedInstanceService.getProviderName() : null;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.SnapshotDto;
import org.sonar.db.metric.MetricDto;
+import org.sonar.db.newcodeperiod.NewCodePeriodDto;
+import org.sonar.db.newcodeperiod.NewCodePeriodType;
import org.sonar.db.qualitygate.QualityGateDto;
import org.sonar.db.user.UserDbTester;
import org.sonar.db.user.UserDto;
import org.sonar.server.property.MapInternalProperties;
import org.sonar.server.qualitygate.QualityGateCaycChecker;
import org.sonar.server.qualitygate.QualityGateFinder;
+import org.sonar.server.telemetry.TelemetryData.NewCodeDefinition;
+import org.sonar.server.telemetry.TelemetryData.ProjectStatistics;
import org.sonar.updatecenter.common.Version;
import static java.util.Arrays.asList;
private final ManagedInstanceService managedInstanceService = mock(ManagedInstanceService.class);
private final TelemetryDataLoader communityUnderTest = new TelemetryDataLoaderImpl(server, db.getDbClient(), pluginRepository, editionProvider,
- internalProperties, configuration, dockerSupport, qualityGateCaycChecker, qualityGateFinder, managedInstanceService);
+ internalProperties, configuration, dockerSupport, qualityGateCaycChecker, qualityGateFinder, managedInstanceService);
private final TelemetryDataLoader commercialUnderTest = new TelemetryDataLoaderImpl(server, db.getDbClient(), pluginRepository, editionProvider,
- internalProperties, configuration, dockerSupport, qualityGateCaycChecker, qualityGateFinder, managedInstanceService);
+ internalProperties, configuration, dockerSupport, qualityGateCaycChecker, qualityGateFinder, managedInstanceService);
private QualityGateDto builtInDefaultQualityGate;
private MetricDto bugsDto;
// link one project to a non-default QG
db.qualityGates().associateProjectToQualityGate(db.components().getProjectDtoByMainBranch(project1), qualityGate1);
+ var branch1 = db.components().insertProjectBranch(project1, branchDto -> branchDto.setKey("reference"));
+ var branch2 = db.components().insertProjectBranch(project1, branchDto -> branchDto.setKey("custom"));
+
+ var ncd1 = db.newCodePeriods().insert(project1.uuid(), NewCodePeriodType.NUMBER_OF_DAYS, "30");
+ var ncd2 = db.newCodePeriods().insert(project1.uuid(), branch2.branchUuid(), NewCodePeriodType.REFERENCE_BRANCH, "reference");
+
+ var instanceNcdId = NewCodeDefinition.getInstanceDefault().hashCode();
+ var projectNcdId = new NewCodeDefinition(NewCodePeriodType.NUMBER_OF_DAYS.name(), "30", "project").hashCode();
+ var branchNcdId = new NewCodeDefinition(NewCodePeriodType.REFERENCE_BRANCH.name(), branch1.uuid(), "branch").hashCode();
+
TelemetryData data = communityUnderTest.load();
assertThat(data.getServerId()).isEqualTo(serverId);
assertThat(data.getVersion()).isEqualTo(version);
assertThat(data.getEdition()).contains(DEVELOPER);
assertThat(data.getDefaultQualityGate()).isEqualTo(builtInDefaultQualityGate.getUuid());
+ assertThat(data.getNcdId()).isEqualTo(NewCodeDefinition.getInstanceDefault().hashCode());
assertThat(data.getMessageSequenceNumber()).isOne();
assertDatabaseMetadata(data.getDatabase());
assertThat(data.getPlugins()).containsOnly(
tuple(project2.uuid(), "java", 180L, analysisDate),
tuple(project2.uuid(), "js", 20L, analysisDate));
assertThat(data.getProjectStatistics())
- .extracting(TelemetryData.ProjectStatistics::getBranchCount, TelemetryData.ProjectStatistics::getPullRequestCount, TelemetryData.ProjectStatistics::getQualityGate,
- TelemetryData.ProjectStatistics::getScm, TelemetryData.ProjectStatistics::getCi, TelemetryData.ProjectStatistics::getDevopsPlatform,
- TelemetryData.ProjectStatistics::getBugs, TelemetryData.ProjectStatistics::getVulnerabilities, TelemetryData.ProjectStatistics::getSecurityHotspots,
- TelemetryData.ProjectStatistics::getDevelopmentCost, TelemetryData.ProjectStatistics::getTechnicalDebt)
+ .extracting(ProjectStatistics::getBranchCount, ProjectStatistics::getPullRequestCount, ProjectStatistics::getQualityGate,
+ ProjectStatistics::getScm, ProjectStatistics::getCi, ProjectStatistics::getDevopsPlatform,
+ ProjectStatistics::getBugs, ProjectStatistics::getVulnerabilities, ProjectStatistics::getSecurityHotspots,
+ ProjectStatistics::getDevelopmentCost, ProjectStatistics::getTechnicalDebt, ProjectStatistics::getNcdId)
+ .containsExactlyInAnyOrder(
+ tuple(3L, 0L, qualityGate1.getUuid(), "scm-1", "ci-1", "azure_devops_cloud", Optional.of(1L), Optional.of(1L), Optional.of(1L), Optional.of(50L), Optional.of(5L),
+ projectNcdId),
+ tuple(1L, 0L, builtInDefaultQualityGate.getUuid(), "scm-2", "ci-2", "github_cloud", Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(),
+ Optional.empty(), instanceNcdId));
+
+ assertThat(data.getBranches())
+ .extracting(TelemetryData.Branch::branchUuid, TelemetryData.Branch::ncdId)
+ .containsExactlyInAnyOrder(
+ tuple(branch1.uuid(), projectNcdId),
+ tuple(branch2.uuid(), branchNcdId),
+ tuple(project1.uuid(), projectNcdId),
+ tuple(project2.uuid(), instanceNcdId));
+
+ assertThat(data.getNewCodeDefinitions())
+ .extracting(NewCodeDefinition::scope, NewCodeDefinition::type, NewCodeDefinition::value)
.containsExactlyInAnyOrder(
- tuple(1L, 0L, qualityGate1.getUuid(), "scm-1", "ci-1", "azure_devops_cloud", Optional.of(1L), Optional.of(1L), Optional.of(1L), Optional.of(50L), Optional.of(5L)),
- tuple(1L, 0L, builtInDefaultQualityGate.getUuid(), "scm-2", "ci-2", "github_cloud", Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty()));
+ tuple("instance", NewCodePeriodType.PREVIOUS_VERSION.name(), ""),
+ tuple("project", NewCodePeriodType.NUMBER_OF_DAYS.name(), "30"),
+ tuple("branch", NewCodePeriodType.REFERENCE_BRANCH.name(), branch1.uuid()));
+
assertThat(data.getQualityGates())
.extracting(TelemetryData.QualityGate::uuid, TelemetryData.QualityGate::caycStatus)
.containsExactlyInAnyOrder(
tuple(project.uuid(), "js", 50L),
tuple(project.uuid(), "kotlin", 30L));
assertThat(data.getProjectStatistics())
- .extracting(TelemetryData.ProjectStatistics::getBranchCount, TelemetryData.ProjectStatistics::getPullRequestCount,
- TelemetryData.ProjectStatistics::getScm, TelemetryData.ProjectStatistics::getCi)
+ .extracting(ProjectStatistics::getBranchCount, ProjectStatistics::getPullRequestCount,
+ ProjectStatistics::getScm, ProjectStatistics::getCi)
.containsExactlyInAnyOrder(
tuple(2L, 0L, "undetected", "undetected"));
}
db.components().insertPublicProject().getMainBranchComponent();
TelemetryData data = communityUnderTest.load();
assertThat(data.getProjectStatistics())
- .extracting(TelemetryData.ProjectStatistics::getDevopsPlatform, TelemetryData.ProjectStatistics::getScm, TelemetryData.ProjectStatistics::getCi)
+ .extracting(ProjectStatistics::getDevopsPlatform, ProjectStatistics::getScm, ProjectStatistics::getCi)
.containsExactlyInAnyOrder(tuple("undetected", "undetected", "undetected"));
}
db.qualityGates().setDefaultQualityGate(qualityGate);
TelemetryData data = communityUnderTest.load();
assertThat(data.getProjectStatistics())
- .extracting(TelemetryData.ProjectStatistics::getQualityGate)
+ .extracting(ProjectStatistics::getQualityGate)
.containsOnly(qualityGate.getUuid());
}
@DataProvider
public static Object[][] getManagedInstanceData() {
- return new Object[][]{
+ return new Object[][] {
{true, "scim"},
{true, "github"},
{true, "gitlab"},