assertThat(underTest.selectProjectAssociations(dbSession, profile3, null)).hasSize(3);
}
+ @Test
+ public void selectAllProjectAssociation_shouldReturnAllProjectsAndQualityProfiles() {
+ ProjectDto project1 = db.components().insertPrivateProject(t -> t.setName("Project1 name")).getProjectDto();
+ ProjectDto project2 = db.components().insertPrivateProject(t -> t.setName("Project2 name")).getProjectDto();
+ ProjectDto project3 = db.components().insertPrivateProject(t -> t.setName("Project3 name")).getProjectDto();
+ db.components().insertProjectBranch(project1, t -> t.setKey("branch"));
+
+ QProfileDto profile1 = newQualityProfileDto();
+ db.qualityProfiles().insert(profile1);
+ db.qualityProfiles().associateWithProject(project1, profile1);
+
+ QProfileDto profile2 = newQualityProfileDto();
+ db.qualityProfiles().insert(profile2);
+ db.qualityProfiles().associateWithProject(project2, profile2);
+ QProfileDto profile3 = newQualityProfileDto();
+
+ assertThat(underTest.selectAllProjectAssociations(dbSession))
+ .extracting("projectUuid", "projectKey", "projectName", "profileKey")
+ .containsExactlyInAnyOrder(
+ tuple(project1.getUuid(), project1.getKey(), project1.getName(), profile1.getKee()),
+ tuple(project2.getUuid(), project2.getKey(), project2.getName(), profile2.getKee())
+ );
+ }
+
+ @Test
+ public void selectAllDefaultProfiles_shouldReturnExpectedProfiles() {
+
+ QProfileDto defaultProfile1 = newQualityProfileDto();
+ db.qualityProfiles().insert(defaultProfile1);
+
+ QProfileDto defaultProfile2 = newQualityProfileDto();
+ db.qualityProfiles().insert(defaultProfile2);
+
+ QProfileDto otherProfile = newQualityProfileDto();
+ db.qualityProfiles().insert(otherProfile);
+
+ db.qualityProfiles().setAsDefault(defaultProfile1, defaultProfile2);
+
+ assertThat(underTest.selectAllDefaultProfiles(dbSession))
+ .extracting("kee", "name", "language")
+ .containsExactlyInAnyOrder(
+ tuple(defaultProfile1.getKee(), defaultProfile1.getName(), defaultProfile1.getLanguage()),
+ tuple(defaultProfile2.getKee(), defaultProfile2.getName(), defaultProfile2.getLanguage())
+ );
+ }
+
@Test
public void selectUuidsOfCustomRulesProfiles_returns_the_custom_profiles_with_specified_name() {
QProfileDto outdatedProfile1 = db.qualityProfiles().insert(p -> p.setIsBuiltIn(false).setLanguage("java").setName("foo"));
return executeLargeInputs(languages, partition -> mapper(dbSession).selectDefaultProfiles(partition));
}
+ public List<QProfileDto> selectAllDefaultProfiles(DbSession dbSession) {
+ return mapper(dbSession).selectAllDefaultProfiles();
+ }
+
public List<QProfileDto> selectDefaultBuiltInProfilesWithoutActiveRules(DbSession dbSession, Set<String> languages) {
return executeLargeInputs(languages, partition -> mapper(dbSession).selectDefaultBuiltInProfilesWithoutActiveRules(partition));
}
return mapper(dbSession).selectProjectAssociations(profile.getKee(), nameQuery);
}
+ public List<ProjectQprofileAssociationDto> selectAllProjectAssociations(DbSession dbSession) {
+ return mapper(dbSession).selectAllProjectAssociations();
+ }
public Collection<String> selectUuidsOfCustomRulesProfiles(DbSession dbSession, String language, String name) {
return mapper(dbSession).selectUuidsOfCustomRuleProfiles(language, name);
}
List<QProfileDto> selectDefaultProfiles(
@Param("languages") Collection<String> languages);
+ List<QProfileDto> selectAllDefaultProfiles();
+
@CheckForNull
String selectDefaultProfileUuid(@Param("language") String language);
@Param("oldProfileUuid") String oldProfileUuid);
void deleteProjectProfileAssociation(@Param("projectUuid") String projectUuid, @Param("profileUuid") String profileUuid);
-
void deleteProjectAssociationByProfileUuids(@Param("profileUuids") Collection<String> profileUuids);
List<ProjectQprofileAssociationDto> selectSelectedProjects(
@Param("profileUuid") String profileUuid,
@Param("nameOrKeyQuery") String nameOrKeyQuery);
+ List<ProjectQprofileAssociationDto> selectAllProjectAssociations();
+
List<String> selectUuidsOfCustomRuleProfiles(@Param("language") String language, @Param("name") String name);
void renameRuleProfiles(@Param("newName") String newName, @Param("updatedAt") Date updatedAt, @Param("uuids") Collection<String> uuids);
and rp.language = dp.language
</select>
+ <select id="selectAllDefaultProfiles" parameterType="map" resultType="org.sonar.db.qualityprofile.QProfileDto">
+ select
+ <include refid="qProfileColumns"/>
+ from org_qprofiles oqp
+ inner join rules_profiles rp on oqp.rules_profile_uuid = rp.uuid
+ inner join default_qprofiles dp on dp.qprofile_uuid = oqp.uuid
+ </select>
+
<select id="selectBuiltInRuleProfilesWithActiveRules" resultType="org.sonar.db.qualityprofile.RulesProfileDto">
select <include refid="ruleProfileColumns"/>
from rules_profiles rp
ORDER BY pj.name ASC
</select>
+ <select id="selectAllProjectAssociations" resultType="org.sonar.db.qualityprofile.ProjectQprofileAssociationDto">
+ SELECT
+ pj.uuid as projectUuid,
+ pj.kee as projectKey,
+ pj.name as projectName,
+ pp.profile_key as profileKey
+ FROM projects pj
+ INNER JOIN project_qprofiles pp ON pp.project_uuid = pj.uuid
+ WHERE
+ pj.qualifier='TRK'
+ </select>
+
<select id="selectUuidsOfCustomRuleProfiles" parameterType="map" resultType="string">
select oqp.rules_profile_uuid
from org_qprofiles oqp
private final List<ProjectStatistics> projectStatistics;
private final List<Branch> branches;
private final List<QualityGate> qualityGates;
+ private final List<QualityProfile> qualityProfiles;
private final Collection<NewCodeDefinition> newCodeDefinitions;
private final Boolean hasUnanalyzedC;
private final Boolean hasUnanalyzedCpp;
projects = builder.projects;
projectStatistics = builder.projectStatistics;
qualityGates = builder.qualityGates;
+ qualityProfiles = builder.qualityProfiles;
hasUnanalyzedC = builder.hasUnanalyzedC;
hasUnanalyzedCpp = builder.hasUnanalyzedCpp;
customSecurityConfigs = requireNonNullElse(builder.customSecurityConfigs, Set.of());
return qualityGates;
}
+ public List<QualityProfile> getQualityProfiles() {
+ return qualityProfiles;
+ }
+
static Builder builder() {
return new Builder();
}
private List<Branch> branches;
private Collection<NewCodeDefinition> newCodeDefinitions;
private List<QualityGate> qualityGates;
+ private List<QualityProfile> qualityProfiles;
private int ncdId;
private Builder() {
return this;
}
+
+ Builder setQualityProfiles(List<QualityProfile> qualityProfiles) {
+ this.qualityProfiles = qualityProfiles;
+ return this;
+ }
+
Builder setNcdId(int ncdId) {
this.ncdId = ncdId;
return this;
record QualityGate(String uuid, String caycStatus) {
}
+ public record QualityProfile(String uuid, @Nullable String parentUuid, String language, boolean isDefault,
+ boolean isBuiltIn,
+ @Nullable Boolean builtInParent, @Nullable Integer rulesOverriddenCount,
+ @Nullable Integer rulesActivatedCount, @Nullable Integer rulesDeactivatedCount
+ ) {
+ }
+
record ManagedInstanceInformation(boolean isManaged, @Nullable String provider) {
}
- record CloudUsage(boolean kubernetes, @Nullable String kubernetesVersion, @Nullable String kubernetesPlatform, @Nullable String kubernetesProvider,
+ record CloudUsage(boolean kubernetes, @Nullable String kubernetesVersion, @Nullable String kubernetesPlatform,
+ @Nullable String kubernetesProvider,
@Nullable String officialHelmChart, @Nullable String containerRuntime, boolean officialImage) {
}
writeBranches(json, telemetryData);
writeNewCodeDefinitions(json, telemetryData);
writeQualityGates(json, telemetryData);
+ writeQualityProfiles(json, telemetryData);
writeManagedInstanceInformation(json, telemetryData.getManagedInstanceInformation());
writeCloudUsage(json, telemetryData.getCloudUsage());
extensions.forEach(e -> e.write(json));
}
}
+ private static void writeQualityProfiles(JsonWriter json, TelemetryData telemetryData) {
+ if (telemetryData.getQualityProfiles() != null) {
+ json.name("quality-profiles");
+ json.beginArray();
+ telemetryData.getQualityProfiles().forEach(qualityProfile -> {
+ json.beginObject();
+ json.prop("uuid", qualityProfile.uuid());
+ json.prop("parentUuid", qualityProfile.parentUuid());
+ json.prop(LANGUAGE_PROPERTY, qualityProfile.language());
+ json.prop("default", qualityProfile.isDefault());
+ json.prop("builtIn", qualityProfile.isBuiltIn());
+ if (qualityProfile.builtInParent() != null) {
+ json.prop("builtInParent", qualityProfile.builtInParent());
+ }
+ json.prop("rulesOverriddenCount", qualityProfile.rulesOverriddenCount());
+ json.prop("rulesActivatedCount", qualityProfile.rulesActivatedCount());
+ json.prop("rulesDeactivatedCount", qualityProfile.rulesDeactivatedCount());
+ json.endObject();
+ });
+ json.endArray();
+ }
+ }
private static void writeManagedInstanceInformation(JsonWriter json, TelemetryData.ManagedInstanceInformation provider) {
json.name(MANAGED_INSTANCE_PROPERTY);
json.beginObject();
);
}
+ @Test
+ public void writeTelemetryData_shouldWriteQualityProfiles() {
+ TelemetryData data = telemetryBuilder()
+ .setQualityProfiles(List.of(
+ new TelemetryData.QualityProfile("uuid-1", "parent-uuid-1", "js", true, false, true, 2, 3, 4),
+ new TelemetryData.QualityProfile("uuid-1", null, "js", false, true, null, null, null, null)))
+ .build();
+
+ String json = writeTelemetryData(data);
+ assertJson(json).isSimilarTo("""
+ {
+ "quality-profiles": [
+ {
+ "uuid": "uuid-1",
+ "parentUuid": "parent-uuid-1",
+ "language": "js",
+ "default": true,
+ "builtIn": false,
+ "builtInParent": true,
+ "rulesOverriddenCount": 2,
+ "rulesActivatedCount": 3,
+ "rulesDeactivatedCount": 4
+ },
+ {
+ "uuid": "uuid-1",
+ "language": "js",
+ "default": false,
+ "builtIn": true
+ }
+ ]}
+ """
+ );
+ }
+
@Test
public void writes_all_branches() {
TelemetryData data = telemetryBuilder()
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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 javax.annotation.Nullable;
+import org.assertj.core.api.Assertions;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbTester;
+import org.sonar.db.component.ProjectData;
+import org.sonar.db.qualityprofile.ActiveRuleDto;
+import org.sonar.db.qualityprofile.ActiveRuleParamDto;
+import org.sonar.db.qualityprofile.QProfileDto;
+import org.sonar.db.rule.RuleDto;
+import org.sonar.db.rule.RuleParamDto;
+import org.sonar.server.qualityprofile.QProfileComparison;
+
+import static org.assertj.core.groups.Tuple.tuple;
+import static org.sonar.db.qualityprofile.ActiveRuleDto.OVERRIDES;
+
+public class QualityProfileDataProviderIT {
+
+ @Rule
+ public DbTester dbTester = DbTester.create(System2.INSTANCE);
+
+ private DbClient dbClient = dbTester.getDbClient();
+
+ QualityProfileDataProvider underTest = new QualityProfileDataProvider(dbClient, new QProfileComparison(dbClient));
+
+ @Test
+ public void retrieveQualityProfilesData_whenDefaultRootProfile_shouldReturnRelevantInformation() {
+ QProfileDto qProfile1 = createQualityProfile(false, null);
+ dbTester.qualityProfiles().setAsDefault(qProfile1);
+ Assertions.assertThat(underTest.retrieveQualityProfilesData())
+ .extracting(p -> p.uuid(), p -> p.isDefault(), p -> p.isBuiltIn(), p -> p.builtInParent(),
+ p -> p.rulesActivatedCount(), p -> p.rulesDeactivatedCount(), p -> p.rulesOverriddenCount())
+ .containsExactlyInAnyOrder(tuple(qProfile1.getKee(), true, false, false, null, null, null));
+ }
+
+ @Test
+ public void retrieveQualityProfilesData_whenDefaultChildProfile_shouldReturnRelevantInformation() {
+ QProfileDto rootProfile = createQualityProfile(false, null);
+
+ QProfileDto childProfile = createQualityProfile(false, rootProfile.getKee());
+
+ dbTester.qualityProfiles().setAsDefault(childProfile);
+ Assertions.assertThat(underTest.retrieveQualityProfilesData())
+ .extracting(p -> p.uuid(), p -> p.isDefault(), p -> p.isBuiltIn(), p -> p.builtInParent(),
+ p -> p.rulesActivatedCount(), p -> p.rulesDeactivatedCount(), p -> p.rulesOverriddenCount())
+ .containsExactlyInAnyOrder(
+ tuple(rootProfile.getKee(), false, false, false, null, null, null),
+ tuple(childProfile.getKee(), true, false, false, null, null, null));
+ }
+
+ @Test
+ public void retrieveQualityProfilesData_whenProfileAssignedToProject_shouldReturnProfile() {
+ ProjectData projectData = dbTester.components().insertPublicProject();
+
+ QProfileDto associatedProfile = createQualityProfile(false, null);
+
+ QProfileDto unassociatedProfile = createQualityProfile(false, null);
+
+ dbTester.qualityProfiles().associateWithProject(projectData.getProjectDto(), associatedProfile);
+
+ Assertions.assertThat(underTest.retrieveQualityProfilesData())
+ .extracting(p -> p.uuid(), p -> p.isDefault())
+ .containsExactlyInAnyOrder(
+ tuple(associatedProfile.getKee(), false),
+ tuple(unassociatedProfile.getKee(), false)
+ );
+ }
+
+ @Test
+ public void retrieveQualityProfilesData_whenBuiltInParent_shouldReturnBuiltInParent() {
+
+ QProfileDto rootBuiltinProfile = createQualityProfile(true, null);
+
+ QProfileDto childProfile = createQualityProfile(false, rootBuiltinProfile.getKee());
+
+ QProfileDto grandChildProfile = createQualityProfile(false, childProfile.getKee());
+
+ dbTester.qualityProfiles().setAsDefault(rootBuiltinProfile, childProfile, grandChildProfile);
+
+ Assertions.assertThat(underTest.retrieveQualityProfilesData())
+ .extracting(p -> p.uuid(), p -> p.isBuiltIn(), p -> p.builtInParent())
+ .containsExactlyInAnyOrder(tuple(rootBuiltinProfile.getKee(), true, null),
+ tuple(childProfile.getKee(), false, true),
+ tuple(grandChildProfile.getKee(), false, true)
+ );
+ }
+
+ @Test
+ public void retrieveQualityProfilesData_whenBuiltInParent_shouldReturnActiveAndUnactiveRules() {
+
+ QProfileDto rootBuiltinProfile = createQualityProfile(true, null);
+
+ QProfileDto childProfile = createQualityProfile(false, rootBuiltinProfile.getKee());
+ RuleDto activatedRule = dbTester.rules().insert();
+ RuleDto deactivatedRule = dbTester.rules().insert();
+
+ dbTester.qualityProfiles().activateRule(rootBuiltinProfile, deactivatedRule);
+ dbTester.qualityProfiles().activateRule(childProfile, activatedRule);
+ dbTester.qualityProfiles().setAsDefault(childProfile);
+
+ Assertions.assertThat(underTest.retrieveQualityProfilesData())
+ .extracting(p -> p.uuid(), p -> p.rulesActivatedCount(), p -> p.rulesDeactivatedCount(), p -> p.rulesOverriddenCount())
+ .containsExactlyInAnyOrder(
+ tuple(rootBuiltinProfile.getKee(), null, null, null),
+ tuple(childProfile.getKee(), 1, 1, 0)
+ );
+ }
+
+ @Test
+ public void retrieveQualityProfilesData_whenBuiltInParent_shouldReturnOverriddenRules() {
+
+ QProfileDto rootBuiltinProfile = createQualityProfile(true, null);
+
+ QProfileDto childProfile = createQualityProfile(false, rootBuiltinProfile.getKee());
+ RuleDto rule = dbTester.rules().insert();
+ RuleParamDto initialRuleParam = dbTester.rules().insertRuleParam(rule, p -> p.setName("key").setDefaultValue("initial"));
+
+
+ ActiveRuleDto activeRuleDto = dbTester.qualityProfiles().activateRule(rootBuiltinProfile, rule);
+ dbTester.getDbClient().activeRuleDao().insertParam(dbTester.getSession(), activeRuleDto, newParam(activeRuleDto, initialRuleParam, "key", "value"));
+
+ ActiveRuleDto childActivateRule = dbTester.qualityProfiles().activateRule(childProfile, rule, ar -> {
+ ar.setInheritance(OVERRIDES);
+ });
+ dbTester.getDbClient().activeRuleDao().insertParam(dbTester.getSession(), activeRuleDto, newParam(childActivateRule, initialRuleParam, "key", "override"));
+
+ dbTester.qualityProfiles().setAsDefault(childProfile);
+
+ Assertions.assertThat(underTest.retrieveQualityProfilesData())
+ .extracting(p -> p.uuid(), p -> p.rulesActivatedCount(), p -> p.rulesDeactivatedCount(), p -> p.rulesOverriddenCount())
+ .containsExactlyInAnyOrder(
+ tuple(rootBuiltinProfile.getKee(), null, null, null),
+ tuple(childProfile.getKee(), 0, 0, 1));
+ }
+
+ private static ActiveRuleParamDto newParam(ActiveRuleDto activeRuleDto, RuleParamDto initial, String key, String value) {
+ return new ActiveRuleParamDto().setActiveRuleUuid(activeRuleDto.getRuleUuid()).setRulesParameterUuid(initial.getUuid()).setKey(key).setValue(value);
+ }
+
+ private QProfileDto createQualityProfile(boolean isBuiltIn, @Nullable String parentKee) {
+ return dbTester.qualityProfiles().insert(p -> {
+ p.setIsBuiltIn(isBuiltIn);
+ p.setParentKee(parentKee);
+ });
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.qualityprofile.QProfileDto;
+import org.sonar.server.qualityprofile.QProfileComparison;
+
+import static java.util.stream.Collectors.toMap;
+
+public class QualityProfileDataProvider {
+
+ private final DbClient dbClient;
+ private final QProfileComparison qProfileComparison;
+
+ public QualityProfileDataProvider(DbClient dbClient, QProfileComparison qProfileComparison) {
+ this.dbClient = dbClient;
+ this.qProfileComparison = qProfileComparison;
+ }
+
+ public List<TelemetryData.QualityProfile> retrieveQualityProfilesData() {
+ try (DbSession dbSession = dbClient.openSession(false)) {
+
+ Set<String> defaultProfileUuids = dbClient.qualityProfileDao().selectAllDefaultProfiles(dbSession)
+ .stream().map(QProfileDto::getKee)
+ .collect(Collectors.toSet());
+
+ Map<String, QProfileDto> allProfileDtosByUuid = dbClient.qualityProfileDao().selectAll(dbSession)
+ .stream()
+ .collect(toMap(QProfileDto::getKee, p -> p));
+
+ return allProfileDtosByUuid.entrySet().stream()
+ .map(p -> mapQualityProfile(p.getValue(), allProfileDtosByUuid, defaultProfileUuids.contains(p.getKey()), dbSession))
+ .toList();
+ }
+ }
+
+ private TelemetryData.QualityProfile mapQualityProfile(QProfileDto profile, Map<String, QProfileDto> allProfileDtos, boolean isDefault, DbSession dbSession) {
+ QProfileDto rootProfile = getRootProfile(profile.getKee(), allProfileDtos);
+ Boolean isBuiltInRootParent;
+ if (profile.isBuiltIn()) {
+ isBuiltInRootParent = null;
+ } else {
+ isBuiltInRootParent = rootProfile.isBuiltIn() && !rootProfile.getKee().equals(profile.getKee());
+ }
+
+ Optional<QProfileComparison.QProfileComparisonResult> rulesComparison = Optional.of(profile)
+ .filter(p -> isBuiltInRootParent != null && isBuiltInRootParent)
+ .map(p -> qProfileComparison.compare(dbSession, rootProfile, profile));
+
+ return new TelemetryData.QualityProfile(profile.getKee(),
+ profile.getParentKee(),
+ profile.getLanguage(),
+ isDefault,
+ profile.isBuiltIn(),
+ isBuiltInRootParent,
+ rulesComparison.map(c -> c.modified().size()).orElse(null),
+ rulesComparison.map(c -> c.inRight().size()).orElse(null),
+ rulesComparison.map(c -> c.inLeft().size()).orElse(null)
+ );
+ }
+
+ public QProfileDto getRootProfile(String kee, Map<String, QProfileDto> allProfileDtos) {
+ QProfileDto qProfileDto = allProfileDtos.get(kee);
+ String parentKee = qProfileDto.getParentKee();
+ if (parentKee != null) {
+ return getRootProfile(parentKee, allProfileDtos);
+ } else {
+ return allProfileDtos.get(kee);
+ }
+ }
+}
private final QualityGateFinder qualityGateFinder;
private final ManagedInstanceService managedInstanceService;
private final CloudUsageDataProvider cloudUsageDataProvider;
+ private final QualityProfileDataProvider qualityProfileDataProvider;
private final Set<NewCodeDefinition> newCodeDefinitions = new HashSet<>();
private final Map<String, NewCodeDefinition> ncdByProject = new HashMap<>();
private final Map<String, NewCodeDefinition> ncdByBranch = new HashMap<>();
public TelemetryDataLoaderImpl(Server server, DbClient dbClient, PluginRepository pluginRepository,
PlatformEditionProvider editionProvider, InternalProperties internalProperties, Configuration configuration,
ContainerSupport containerSupport, QualityGateCaycChecker qualityGateCaycChecker, QualityGateFinder qualityGateFinder,
- ManagedInstanceService managedInstanceService, CloudUsageDataProvider cloudUsageDataProvider) {
+ ManagedInstanceService managedInstanceService, CloudUsageDataProvider cloudUsageDataProvider, QualityProfileDataProvider qualityProfileDataProvider) {
this.server = server;
this.dbClient = dbClient;
this.pluginRepository = pluginRepository;
this.qualityGateFinder = qualityGateFinder;
this.managedInstanceService = managedInstanceService;
this.cloudUsageDataProvider = cloudUsageDataProvider;
+ this.qualityProfileDataProvider = qualityProfileDataProvider;
}
private static Database loadDatabaseMetadata(DbSession dbSession) {
resolveUsers(data, dbSession);
}
+ data.setQualityProfiles(qualityProfileDataProvider.retrieveQualityProfilesData());
+
setSecurityCustomConfigIfPresent(data);
Optional<String> installationDateProperty = internalProperties.read(InternalProperties.INSTALLATION_DATE);
data.setQualityGates(qualityGates);
}
+
+
private void resolveUsers(TelemetryData.Builder data, DbSession dbSession) {
data.setUsers(dbClient.userDao().selectUsersForTelemetry(dbSession));
}
import org.sonar.db.DbTester;
import org.sonar.db.alm.setting.AlmSettingDto;
import org.sonar.db.component.AnalysisPropertyDto;
-import org.sonar.db.component.BranchDto;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ProjectData;
import org.sonar.db.component.SnapshotDto;
import org.sonar.db.newcodeperiod.NewCodePeriodType;
import org.sonar.db.property.PropertyDto;
import org.sonar.db.qualitygate.QualityGateDto;
+import org.sonar.db.qualityprofile.QProfileDto;
import org.sonar.db.user.UserDbTester;
import org.sonar.db.user.UserDto;
import org.sonar.db.user.UserTelemetryDto;
import org.sonar.server.property.MapInternalProperties;
import org.sonar.server.qualitygate.QualityGateCaycChecker;
import org.sonar.server.qualitygate.QualityGateFinder;
+import org.sonar.server.qualityprofile.QProfileComparison;
import org.sonar.server.telemetry.TelemetryData.Branch;
import org.sonar.server.telemetry.TelemetryData.CloudUsage;
import org.sonar.server.telemetry.TelemetryData.NewCodeDefinition;
private final ContainerSupport containerSupport = mock(ContainerSupport.class);
private final QualityGateCaycChecker qualityGateCaycChecker = mock(QualityGateCaycChecker.class);
private final QualityGateFinder qualityGateFinder = new QualityGateFinder(db.getDbClient());
+
+ private final QualityProfileDataProvider qualityProfileDataProvider = new QualityProfileDataProvider(db.getDbClient(), new QProfileComparison(db.getDbClient()));
private final InternalProperties internalProperties = spy(new MapInternalProperties());
private final ManagedInstanceService managedInstanceService = mock(ManagedInstanceService.class);
private final CloudUsageDataProvider cloudUsageDataProvider = mock(CloudUsageDataProvider.class);
private final TelemetryDataLoader communityUnderTest = new TelemetryDataLoaderImpl(server, db.getDbClient(), pluginRepository, editionProvider,
- internalProperties, configuration, containerSupport, qualityGateCaycChecker, qualityGateFinder, managedInstanceService, cloudUsageDataProvider);
+ internalProperties, configuration, containerSupport, qualityGateCaycChecker, qualityGateFinder, managedInstanceService, cloudUsageDataProvider, qualityProfileDataProvider);
private final TelemetryDataLoader commercialUnderTest = new TelemetryDataLoaderImpl(server, db.getDbClient(), pluginRepository, editionProvider,
- internalProperties, configuration, containerSupport, qualityGateCaycChecker, qualityGateFinder, managedInstanceService, cloudUsageDataProvider);
+ internalProperties, configuration, containerSupport, qualityGateCaycChecker, qualityGateFinder, managedInstanceService, cloudUsageDataProvider, qualityProfileDataProvider);
private QualityGateDto builtInDefaultQualityGate;
private MetricDto bugsDto;
QualityGateDto qualityGate1 = db.qualityGates().insertQualityGate(qg -> qg.setName("QG1").setBuiltIn(true));
QualityGateDto qualityGate2 = db.qualityGates().insertQualityGate(qg -> qg.setName("QG2"));
+ //quality profiles
+ QProfileDto qualityProfile1 = db.qualityProfiles().insert(qp -> qp.setIsBuiltIn(true));
+ QProfileDto qualityProfile2 = db.qualityProfiles().insert();
+ db.qualityProfiles().setAsDefault(qualityProfile1, qualityProfile2);
+
// link one project to a non-default QG
db.qualityGates().associateProjectToQualityGate(db.components().getProjectDtoByMainBranch(mainBranch1), qualityGate1);
tuple(qualityGate1.getUuid(), "non-compliant"),
tuple(qualityGate2.getUuid(), "non-compliant")
);
+
+ assertThat(data.getQualityProfiles())
+ .extracting(TelemetryData.QualityProfile::uuid, TelemetryData.QualityProfile::isBuiltIn)
+ .containsExactlyInAnyOrder(tuple(qualityProfile1.getKee(), qualityProfile1.isBuiltIn()), tuple(qualityProfile2.getKee(), qualityProfile2.isBuiltIn()));
+
}
@Test
@DataProvider
public static Object[][] getManagedInstanceData() {
- return new Object[][] {
+ return new Object[][]{
{true, "scim"},
{true, "github"},
{true, "gitlab"},
import org.sonar.server.source.ws.SourceWsModule;
import org.sonar.server.startup.LogServerId;
import org.sonar.server.telemetry.CloudUsageDataProvider;
+import org.sonar.server.telemetry.QualityProfileDataProvider;
import org.sonar.server.telemetry.TelemetryClient;
import org.sonar.server.telemetry.TelemetryDaemon;
import org.sonar.server.telemetry.TelemetryDataJsonWriter;
TelemetryDaemon.class,
TelemetryClient.class,
CloudUsageDataProvider.class,
+ QualityProfileDataProvider.class,
// monitoring
ServerMonitoringMetrics.class,