diff options
author | Benjamin Campomenosi <109955405+benjamin-campomenosi-sonarsource@users.noreply.github.com> | 2023-04-21 18:25:51 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2023-04-24 20:04:24 +0000 |
commit | 907bb0a96d2dc0d9ea3de71547f57eb1f85402eb (patch) | |
tree | b8bb2a423ba19d8241f542ff510742334d37beb1 | |
parent | 5b132ad8eedf204ba28af43e68a6c2ccd13dfa4e (diff) | |
download | sonarqube-907bb0a96d2dc0d9ea3de71547f57eb1f85402eb.tar.gz sonarqube-907bb0a96d2dc0d9ea3de71547f57eb1f85402eb.zip |
SONAR-19050 Populate characteristic RuleDto during RegisterRule
7 files changed, 59 insertions, 32 deletions
diff --git a/build.gradle b/build.gradle index a2ecef603cc..467cd1a9935 100644 --- a/build.gradle +++ b/build.gradle @@ -215,8 +215,8 @@ subprojects { dependency 'org.sonarsource.kotlin:sonar-kotlin-plugin:2.13.0.2116' dependency 'org.sonarsource.slang:sonar-ruby-plugin:1.12.0.4259' dependency 'org.sonarsource.slang:sonar-scala-plugin:1.12.0.4259' - dependency "org.sonarsource.api.plugin:sonar-plugin-api:9.16.0.500" - dependency "org.sonarsource.api.plugin:sonar-plugin-api-test-fixtures:9.16.0.500" + dependency "org.sonarsource.api.plugin:sonar-plugin-api:$pluginApiVersion" + dependency "org.sonarsource.api.plugin:sonar-plugin-api-test-fixtures:$pluginApiVersion" dependency 'org.sonarsource.xml:sonar-xml-plugin:2.7.0.3820' dependency 'org.sonarsource.iac:sonar-iac-plugin:1.15.0.3752' dependency 'org.sonarsource.text:sonar-text-plugin:2.0.2.1090' diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/rule/RuleDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/rule/RuleDaoIT.java index 59f9bd5f29d..ec138783b03 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/rule/RuleDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/rule/RuleDaoIT.java @@ -521,6 +521,7 @@ public class RuleDaoIT { .setSecurityStandards(newHashSet("owaspTop10:a1", "cwe:123")) .setScope(Scope.ALL) .setType(RuleType.BUG) + .setCharacteristic(RuleCharacteristic.PORTABLE) .setUpdatedAt(2_000_000_000_000L); underTest.update(db.getSession(), ruleToUpdate); @@ -546,6 +547,7 @@ public class RuleDaoIT { assertThat(ruleDto.getSecurityStandards()).containsOnly("owaspTop10:a1", "cwe:123"); assertThat(ruleDto.getScope()).isEqualTo(Scope.ALL); assertThat(ruleDto.getType()).isEqualTo(RuleType.BUG.getDbConstant()); + assertThat(ruleDto.getCharacteristic()).isEqualTo(RuleCharacteristic.PORTABLE); assertThat(ruleDto.getCreatedAt()).isEqualTo(rule.getCreatedAt()); assertThat(ruleDto.getUpdatedAt()).isEqualTo(2_000_000_000_000L); assertThat(ruleDto.getDescriptionFormat()).isEqualTo(RuleDto.Format.MARKDOWN); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java index dbacc89df55..5a01ffd4ff4 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/rule/RuleDto.java @@ -406,7 +406,7 @@ public class RuleDto { return characteristic != null ? characteristic : RuleTypeToRuleCharacteristicConverter.convertToRuleCharacteristic(type); } - public RuleDto setCharacteristic(RuleCharacteristic characteristic) { + public RuleDto setCharacteristic(@Nullable RuleCharacteristic characteristic) { this.characteristic = characteristic; return this; } diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/rule/RuleMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/rule/RuleMapper.xml index e481e9a3930..8bf29f59950 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/rule/RuleMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/rule/RuleMapper.xml @@ -344,6 +344,7 @@ security_standards=#{securityStandardsField,jdbcType=VARCHAR}, scope=#{scope,jdbcType=VARCHAR}, rule_type=#{type,jdbcType=TINYINT}, + characteristic=#{characteristic,jdbcType=VARCHAR}, note_data=#{noteData,jdbcType=CLOB}, note_user_uuid=#{noteUserUuid,jdbcType=VARCHAR}, note_created_at=#{noteCreatedAt,jdbcType=BIGINT}, diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDtoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDtoTest.java index f4b09aaa120..fc701c189ae 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDtoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/rule/RuleDtoTest.java @@ -41,7 +41,6 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.sonar.db.rule.RuleDto.ERROR_MESSAGE_SECTION_ALREADY_EXISTS; import static org.sonar.db.rule.RuleTesting.newRule; -@RunWith(DataProviderRunner.class) public class RuleDtoTest { public static final String SECTION_KEY = "section key"; diff --git a/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/RegisterRules.java b/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/RegisterRules.java index 6dfc0e417fa..6cf042a4273 100644 --- a/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/RegisterRules.java +++ b/server/sonar-webserver-core/src/main/java/org/sonar/server/rule/RegisterRules.java @@ -43,6 +43,7 @@ import org.sonar.api.resources.Languages; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleScope; import org.sonar.api.rule.RuleStatus; +import org.sonar.api.rules.RuleCharacteristic; import org.sonar.api.rules.RuleType; import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.api.server.rule.RulesDefinition; @@ -100,7 +101,6 @@ public class RegisterRules implements Startable { private final MetadataIndex metadataIndex; private final RuleDescriptionSectionsGeneratorResolver ruleDescriptionSectionsGeneratorResolver; - public RegisterRules(RuleDefinitionsLoader defLoader, QProfileRules qProfileRules, DbClient dbClient, RuleIndexer ruleIndexer, ActiveRuleIndexer activeRuleIndexer, Languages languages, System2 system2, WebServerRuleFinder webServerRuleFinder, UuidFactory uuidFactory, MetadataIndex metadataIndex, @@ -209,7 +209,7 @@ public class RegisterRules implements Startable { RuleDto rule = dbRulesByRuleUuid.get(ruleUuid); if (rule == null) { LOG.warn("Could not retrieve rule with uuid %s referenced by a deprecated rule key. " + - "The following deprecated rule keys seem to be referencing a non-existing rule", + "The following deprecated rule keys seem to be referencing a non-existing rule", ruleUuid, entry.getValue()); } else { entry.getValue().forEach(d -> rulesByKey.put(d.getOldRuleKeyAsRuleKey(), rule)); @@ -268,10 +268,10 @@ public class RegisterRules implements Startable { private Stream<RuleDto> getAllModified() { return Stream.of( - created.stream(), - updated.stream(), - removed.stream(), - renamed.keySet().stream()) + created.stream(), + updated.stream(), + removed.stream(), + renamed.keySet().stream()) .flatMap(s -> s); } @@ -391,7 +391,8 @@ public class RegisterRules implements Startable { .setGapDescription(ruleDef.gapDescription()) .setSystemTags(ruleDef.tags()) .setSecurityStandards(ruleDef.securityStandards()) - .setType(RuleType.valueOf(ruleDef.type().name())) + .setType(ruleDef.type()) + .setCharacteristic(ruleDef.characteristic()) .setScope(toDtoScope(ruleDef.scope())) .setIsExternal(ruleDef.repository().isExternal()) .setIsAdHoc(false) @@ -486,11 +487,17 @@ public class RegisterRules implements Startable { dto.setLanguage(def.repository().language()); changed = true; } - RuleType type = RuleType.valueOf(def.type().name()); + RuleType type = def.type(); if (!Objects.equals(dto.getType(), type.getDbConstant())) { dto.setType(type); changed = true; } + RuleCharacteristic characteristic = def.characteristic(); + if (!Objects.equals(dto.getCharacteristic(), characteristic)) { + dto.setCharacteristic(characteristic); + changed = true; + } + if (dto.isAdHoc()) { dto.setIsAdHoc(false); changed = true; @@ -663,9 +670,9 @@ public class RegisterRules implements Startable { changed = true; } else if (dto.getSystemTags().size() != ruleDef.tags().size() || !dto.getSystemTags().containsAll(ruleDef.tags())) { - dto.setSystemTags(ruleDef.tags()); - changed = true; - } + dto.setSystemTags(ruleDef.tags()); + changed = true; + } return changed; } @@ -677,9 +684,9 @@ public class RegisterRules implements Startable { changed = true; } else if (dto.getSecurityStandards().size() != ruleDef.securityStandards().size() || !dto.getSecurityStandards().containsAll(ruleDef.securityStandards())) { - dto.setSecurityStandards(ruleDef.securityStandards()); - changed = true; - } + dto.setSecurityStandards(ruleDef.securityStandards()); + changed = true; + } return changed; } @@ -811,8 +818,8 @@ public class RegisterRules implements Startable { private static Set<String> getExistingAndRenamedRepositories(RegisterRulesContext recorder, Collection<RulesDefinition.Repository> context) { return Stream.concat( - context.stream().map(RulesDefinition.ExtendedRepository::key), - recorder.getRenamed().map(Map.Entry::getValue).map(RuleKey::repository)) + context.stream().map(RulesDefinition.ExtendedRepository::key), + recorder.getRenamed().map(Map.Entry::getValue).map(RuleKey::repository)) .collect(toSet()); } diff --git a/server/sonar-webserver-core/src/test/java/org/sonar/server/rule/RegisterRulesTest.java b/server/sonar-webserver-core/src/test/java/org/sonar/server/rule/RegisterRulesTest.java index 89a8a76de27..ff98036da12 100644 --- a/server/sonar-webserver-core/src/test/java/org/sonar/server/rule/RegisterRulesTest.java +++ b/server/sonar-webserver-core/src/test/java/org/sonar/server/rule/RegisterRulesTest.java @@ -42,6 +42,7 @@ import org.sonar.api.resources.Languages; import org.sonar.api.rule.RuleKey; import org.sonar.api.rule.RuleScope; import org.sonar.api.rule.RuleStatus; +import org.sonar.api.rules.RuleCharacteristic; import org.sonar.api.rules.RuleType; import org.sonar.api.server.debt.DebtRemediationFunction; import org.sonar.api.server.rule.Context; @@ -164,8 +165,7 @@ public class RegisterRulesTest { .key(s.getKey()) .content(s.getHtmlContent()) .context(s.getContext().map(c -> RuleDescriptionSectionContextDto.of(c.getKey(), c.getDisplayName())).orElse(null)) - .build() - ) + .build()) .collect(Collectors.toSet()); return Sets.union(ruleDescriptionSectionDtos, Set.of(builder().uuid(UuidFactoryFast.getInstance().create()).key("default").content(description).build())); }); @@ -210,6 +210,7 @@ public class RegisterRulesTest { assertThat(hotspotRule.getCreatedAt()).isEqualTo(RegisterRulesTest.DATE1.getTime()); assertThat(hotspotRule.getUpdatedAt()).isEqualTo(RegisterRulesTest.DATE1.getTime()); assertThat(hotspotRule.getType()).isEqualTo(RuleType.SECURITY_HOTSPOT.getDbConstant()); + assertThat(hotspotRule.getCharacteristic()).isEqualTo(RuleCharacteristic.SECURE); assertThat(hotspotRule.getSecurityStandards()).containsExactly("cwe:1", "cwe:123", "cwe:863", "owaspTop10-2021:a1", "owaspTop10-2021:a3"); } @@ -220,7 +221,7 @@ public class RegisterRulesTest { // verify db assertThat(dbClient.ruleDao().selectAll(db.getSession())).hasSize(2); RuleDto rule1 = dbClient.ruleDao().selectOrFailByKey(db.getSession(), EXTERNAL_RULE_KEY1); - verifyRule(rule1); + verifyExternalRule(rule1); assertThat(rule1.isExternal()).isTrue(); assertThat(rule1.getDefRemediationFunction()).isNull(); assertThat(rule1.getDefRemediationGapMultiplier()).isNull(); @@ -231,6 +232,15 @@ public class RegisterRulesTest { } private void verifyRule(RuleDto rule) { + verifyCommonsFields(rule); + } + + private void verifyExternalRule(RuleDto rule) { + verifyCommonsFields(rule); + assertThat(rule.getCharacteristic()).isEqualTo(RuleCharacteristic.COMPLIANT); + } + + private void verifyCommonsFields(RuleDto rule) { assertThat(rule.getName()).isEqualTo("One"); assertThat(rule.getDefaultRuleDescriptionSection().getContent()).isEqualTo("Description of One"); assertThat(rule.getSeverityString()).isEqualTo(BLOCKER); @@ -412,9 +422,10 @@ public class RegisterRulesTest { assertThat(rule1.getNoteUserUuid()).isEqualTo("marius"); assertThat(rule1.getStatus()).isEqualTo(READY); assertThat(rule1.getType()).isEqualTo(RuleType.BUG.getDbConstant()); + assertThat(rule1.getCharacteristic()).isEqualTo(RuleCharacteristic.PORTABLE); assertThat(rule1.getCreatedAt()).isEqualTo(DATE1.getTime()); assertThat(rule1.getUpdatedAt()).isEqualTo(DATE2.getTime()); - assertThat(rule1.getEducationPrinciples()).containsOnly("concept1","concept4"); + assertThat(rule1.getEducationPrinciples()).containsOnly("concept1", "concept4"); } @Test @@ -665,7 +676,7 @@ public class RegisterRulesTest { @DataProvider public static Object[][] allRenamingCases() { - return new Object[][]{ + return new Object[][] { {"repo1", "rule1", "repo1", "rule2"}, {"repo1", "rule1", "repo2", "rule1"}, {"repo1", "rule1", "repo2", "rule2"}, @@ -748,7 +759,7 @@ public class RegisterRulesTest { RuleDescriptionSection section1context1 = createRuleDescriptionSection(HOW_TO_FIX_SECTION_KEY, "section1 ctx1 content", "ctx_1"); RuleDescriptionSection section1context2 = createRuleDescriptionSection(HOW_TO_FIX_SECTION_KEY, "section1 ctx2 content", "ctx_2"); RuleDescriptionSection section2context1 = createRuleDescriptionSection(RESOURCES_SECTION_KEY, "section2 content", "ctx_1"); - RuleDescriptionSection section2context2 = createRuleDescriptionSection(RESOURCES_SECTION_KEY,"section2 ctx2 content", "ctx_2"); + RuleDescriptionSection section2context2 = createRuleDescriptionSection(RESOURCES_SECTION_KEY, "section2 ctx2 content", "ctx_2"); RuleDescriptionSection section3noContext = createRuleDescriptionSection(ASSESS_THE_PROBLEM_SECTION_KEY, "section3 content", null); RuleDescriptionSection section4noContext = createRuleDescriptionSection(ROOT_CAUSE_SECTION_KEY, "section4 content", null); execute(context -> { @@ -1108,15 +1119,15 @@ public class RegisterRulesTest { @Test public void removed_rule_should_appear_in_changelog() { - //GIVEN + // GIVEN QProfileDto qProfileDto = db.qualityProfiles().insert(); RuleDto ruleDto = db.rules().insert(RULE_KEY1); db.qualityProfiles().activateRule(qProfileDto, ruleDto); ActiveRuleChange arChange = new ActiveRuleChange(DEACTIVATED, ActiveRuleDto.createFor(qProfileDto, ruleDto), ruleDto); when(qProfileRules.deleteRule(any(DbSession.class), eq(ruleDto))).thenReturn(List.of(arChange)); - //WHEN + // WHEN execute(context -> context.createRepository("fake", "java").done()); - //THEN + // THEN List<QProfileChangeDto> qProfileChangeDtos = dbClient.qProfileChangeDao().selectByQuery(db.getSession(), new QProfileChangeQuery(qProfileDto.getKee())); assertThat(qProfileChangeDtos).extracting(QProfileChangeDto::getRulesProfileUuid, QProfileChangeDto::getChangeType) .contains(tuple(qProfileDto.getRulesProfileUuid(), "DEACTIVATED")); @@ -1124,13 +1135,13 @@ public class RegisterRulesTest { @Test public void removed_rule_should_be_deleted_when_renamed_repository() { - //GIVEN + // GIVEN RuleDto removedRuleDto = db.rules().insert(RuleKey.of("old_repo", "removed_rule")); RuleDto renamedRuleDto = db.rules().insert(RuleKey.of("old_repo", "renamed_rule")); - //WHEN + // WHEN execute(context -> createRule(context, "java", "new_repo", renamedRuleDto.getRuleKey(), rule -> rule.addDeprecatedRuleKey(renamedRuleDto.getRepositoryKey(), renamedRuleDto.getRuleKey()))); - //THEN + // THEN verify(qProfileRules).deleteRule(any(DbSession.class), eq(removedRuleDto)); } @@ -1159,6 +1170,7 @@ public class RegisterRulesTest { .setInternalKey("config1") .setTags("tag1", "tag2", "tag3") .setType(RuleType.CODE_SMELL) + .setCharacteristic(RuleCharacteristic.ROBUST) .setStatus(RuleStatus.BETA); } @@ -1170,6 +1182,7 @@ public class RegisterRulesTest { .setHtmlDescription("Description of One") .setSeverity(BLOCKER) .setType(RuleType.CODE_SMELL) + .setCharacteristic(RuleCharacteristic.TESTED) .setStatus(RuleStatus.BETA); Arrays.stream(consumers).forEach(c -> c.accept(newRule)); @@ -1207,6 +1220,7 @@ public class RegisterRulesTest { .setTags("tag1", "tag2", "tag3") .setScope(RuleScope.ALL) .setType(RuleType.CODE_SMELL) + .setCharacteristic(RuleCharacteristic.CLEAR) .setStatus(RuleStatus.BETA) .setGapDescription("java.S115.effortToFix") .addEducationPrincipleKeys("concept1", "concept2", "concept3"); @@ -1219,6 +1233,7 @@ public class RegisterRulesTest { .setName("Hotspot") .setHtmlDescription("Minimal hotspot") .setType(RuleType.SECURITY_HOTSPOT) + .setCharacteristic(RuleCharacteristic.SECURE) .addOwaspTop10(Y2021, OwaspTop10.A1, OwaspTop10.A3) .addCwe(1, 123, 863); @@ -1246,6 +1261,7 @@ public class RegisterRulesTest { // tag2 and tag3 removed, tag4 added .setTags("tag1", "tag4") .setType(RuleType.BUG) + .setCharacteristic(RuleCharacteristic.PORTABLE) .setStatus(READY) .setGapDescription("java.S115.effortToFix.v2") .addEducationPrincipleKeys("concept1", "concept4"); @@ -1287,6 +1303,7 @@ public class RegisterRulesTest { .setTags("tag1", "tag2", "tag3") .setScope(RuleScope.ALL) .setType(RuleType.CODE_SMELL) + .setCharacteristic(RuleCharacteristic.COMPLIANT) .setStatus(RuleStatus.BETA) .addEducationPrincipleKeys("concept1", "concept2", "concept3"); @@ -1294,6 +1311,7 @@ public class RegisterRulesTest { .setName("Hotspot") .setHtmlDescription("Minimal hotspot") .setType(RuleType.SECURITY_HOTSPOT) + .setCharacteristic(RuleCharacteristic.SECURE) .addOwaspTop10(Y2021, OwaspTop10.A1, OwaspTop10.A3) .addCwe(1, 123, 863); |