aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-webserver-auth
diff options
context:
space:
mode:
authorJacek <jacek.poreda@sonarsource.com>2021-04-28 14:17:43 +0200
committersonartech <sonartech@sonarsource.com>2021-05-04 20:08:04 +0000
commit71876a9a53fd2562c00d2eb135d3141d3591862c (patch)
tree205b4faf42bb05292973f3230c261e9b46d13960 /server/sonar-webserver-auth
parent9d9807e4902eecbc5f086fa60adacabec4f209d5 (diff)
downloadsonarqube-71876a9a53fd2562c00d2eb135d3141d3591862c.tar.gz
sonarqube-71876a9a53fd2562c00d2eb135d3141d3591862c.zip
SONAR-14559 Update active rule for descendant when rule inherited
Diffstat (limited to 'server/sonar-webserver-auth')
-rw-r--r--server/sonar-webserver-auth/src/main/java/org/sonar/server/qualityprofile/RuleActivator.java114
-rw-r--r--server/sonar-webserver-auth/src/test/java/org/sonar/server/qualityprofile/BuiltInQProfileUpdateImplTest.java95
-rw-r--r--server/sonar-webserver-auth/src/test/java/org/sonar/server/qualityprofile/RuleActivatorTest.java207
3 files changed, 378 insertions, 38 deletions
diff --git a/server/sonar-webserver-auth/src/main/java/org/sonar/server/qualityprofile/RuleActivator.java b/server/sonar-webserver-auth/src/main/java/org/sonar/server/qualityprofile/RuleActivator.java
index 6b56e27aa8c..80fe80d8423 100644
--- a/server/sonar-webserver-auth/src/main/java/org/sonar/server/qualityprofile/RuleActivator.java
+++ b/server/sonar-webserver-auth/src/main/java/org/sonar/server/qualityprofile/RuleActivator.java
@@ -161,60 +161,106 @@ public class RuleActivator {
ActiveRuleWrapper activeRule = context.getActiveRule();
ActiveRuleWrapper parentActiveRule = context.getParentActiveRule();
- // First apply severity
- String severity;
if (request.isReset()) {
- // load severity from parent profile, else from default values
- severity = firstNonNull(
- parentActiveRule != null ? parentActiveRule.get().getSeverityString() : null,
- rule.get().getSeverityString());
+ applySeverityAndParamsWhenResetRequested(change, rule, parentActiveRule);
} else if (context.getRulesProfile().isBuiltIn()) {
- // for builtin quality profiles, the severity from profile, when null use the default severity of the rule
- severity = firstNonNull(request.getSeverity(), rule.get().getSeverityString());
+ applySeverityAndParamsWhenBuiltInProfile(request, context, change, rule);
} else {
- // load severity from request, else keep existing one (if already activated), else from parent, else from default
- severity = firstNonNull(
- request.getSeverity(),
- activeRule == null ? null : activeRule.get().getSeverityString(),
- parentActiveRule != null ? parentActiveRule.get().getSeverityString() : null,
- rule.get().getSeverityString());
+ applySeverityAndParamsWhenNonBuiltInProfile(request, context, change, rule, activeRule, parentActiveRule);
+ }
+ }
+
+ private void applySeverityAndParamsWhenResetRequested(ActiveRuleChange change, RuleWrapper rule, @Nullable ActiveRuleWrapper parentActiveRule) {
+ String severity = firstNonNull(
+ parentActiveRule != null ? parentActiveRule.get().getSeverityString() : null,
+ rule.get().getSeverityString());
+ change.setSeverity(severity);
+
+ for (RuleParamDto ruleParamDto : rule.getParams()) {
+ String paramKey = ruleParamDto.getName();
+ // load params from parent profile, else from default values
+ String paramValue = firstNonNull(
+ parentActiveRule != null ? parentActiveRule.getParamValue(paramKey) : null,
+ rule.getParamDefaultValue(paramKey));
+
+ change.setParameter(paramKey, validateParam(ruleParamDto, paramValue));
+ }
+ }
+
+ private void applySeverityAndParamsWhenBuiltInProfile(RuleActivation request, RuleActivationContext context, ActiveRuleChange change,
+ RuleWrapper rule) {
+ // for builtin quality profiles, the severity from profile, when null use the default severity of the rule
+ String severity = firstNonNull(request.getSeverity(), rule.get().getSeverityString());
+ change.setSeverity(severity);
+
+ for (RuleParamDto ruleParamDto : rule.getParams()) {
+ String paramKey = ruleParamDto.getName();
+ // use the value defined in the profile definition, else the rule default value
+ String paramValue = firstNonNull(
+ context.getRequestedParamValue(request, paramKey),
+ rule.getParamDefaultValue(paramKey));
+ change.setParameter(paramKey, validateParam(ruleParamDto, paramValue));
}
+ }
+
+ /**
+ * 1. apply requested severity and param
+ * 2. if rule activated and overridden - apply user value
+ * 3. apply parent value
+ * 4. apply defaults
+ */
+ private void applySeverityAndParamsWhenNonBuiltInProfile(RuleActivation request, RuleActivationContext context, ActiveRuleChange change,
+ RuleWrapper rule, @Nullable ActiveRuleWrapper activeRule, @Nullable ActiveRuleWrapper parentActiveRule) {
+ String severity = getSeverityForNonBuiltInProfile(request, rule, activeRule, parentActiveRule);
change.setSeverity(severity);
- // Apply param values
for (RuleParamDto ruleParamDto : rule.getParams()) {
String paramKey = ruleParamDto.getName();
+ String parentValue = parentActiveRule != null ? parentActiveRule.getParamValue(paramKey) : null;
String paramValue;
- if (request.isReset()) {
- // load params from parent profile, else from default values
+ if (context.hasRequestedParamValue(request, paramKey)) {
+ // If the request contains the parameter then we're using either value from request, or parent value, or default value
paramValue = firstNonNull(
- parentActiveRule != null ? parentActiveRule.getParamValue(paramKey) : null,
+ context.getRequestedParamValue(request, paramKey),
+ parentValue,
rule.getParamDefaultValue(paramKey));
- } else if (context.getRulesProfile().isBuiltIn()) {
- // use the value defined in the profile definition, else the rule default value
+ } else if (activeRule != null) {
+ // If the request doesn't contain the parameter, then we're using either user value from db, or parent value if rule inherited, or default
+ // value
paramValue = firstNonNull(
- context.getRequestedParamValue(request, paramKey),
+ activeRule.get().doesOverride() ? activeRule.getParamValue(paramKey) : null,
+ parentValue == null ? activeRule.getParamValue(paramKey) : parentValue,
rule.getParamDefaultValue(paramKey));
} else {
- String parentValue = parentActiveRule != null ? parentActiveRule.getParamValue(paramKey) : null;
- String activeRuleValue = activeRule == null ? null : activeRule.getParamValue(paramKey);
- paramValue = context.hasRequestedParamValue(request, paramKey) ?
- // If the request contains the parameter then we're using either value from request, or parent value, or default value
- firstNonNull(
- context.getRequestedParamValue(request, paramKey),
+ paramValue = firstNonNull(
parentValue,
- rule.getParamDefaultValue(paramKey))
- // If the request doesn't contain the parameter, then we're using either value in DB, or parent value, or default value
- : firstNonNull(
- activeRuleValue,
- parentValue,
- rule.getParamDefaultValue(paramKey));
+ rule.getParamDefaultValue(paramKey));
}
-
change.setParameter(paramKey, validateParam(ruleParamDto, paramValue));
}
}
+ private static String getSeverityForNonBuiltInProfile(RuleActivation request, RuleWrapper rule, @Nullable ActiveRuleWrapper activeRule,
+ @Nullable ActiveRuleWrapper parentActiveRule) {
+ String severity;
+ if (activeRule != null) {
+ ActiveRuleDto activeRuleDto = activeRule.get();
+ // load severity from request, else keep existing one (if overridden), else from parent if rule inherited, else from default
+ severity = firstNonNull(
+ request.getSeverity(),
+ activeRuleDto.doesOverride() ? activeRuleDto.getSeverityString() : null,
+ parentActiveRule != null ? parentActiveRule.get().getSeverityString() : activeRuleDto.getSeverityString(),
+ rule.get().getSeverityString());
+ } else {
+ // load severity from request, else from parent, else from default
+ severity = firstNonNull(
+ request.getSeverity(),
+ parentActiveRule != null ? parentActiveRule.get().getSeverityString() : null,
+ rule.get().getSeverityString());
+ }
+ return severity;
+ }
+
private List<ActiveRuleChange> propagateActivationToDescendants(DbSession dbSession, RuleActivation activation, RuleActivationContext context) {
List<ActiveRuleChange> changes = new ArrayList<>();
diff --git a/server/sonar-webserver-auth/src/test/java/org/sonar/server/qualityprofile/BuiltInQProfileUpdateImplTest.java b/server/sonar-webserver-auth/src/test/java/org/sonar/server/qualityprofile/BuiltInQProfileUpdateImplTest.java
index d3716ea34a0..dde53fb8f1b 100644
--- a/server/sonar-webserver-auth/src/test/java/org/sonar/server/qualityprofile/BuiltInQProfileUpdateImplTest.java
+++ b/server/sonar-webserver-auth/src/test/java/org/sonar/server/qualityprofile/BuiltInQProfileUpdateImplTest.java
@@ -29,6 +29,7 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.impl.utils.TestSystem2;
+import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.Severity;
import org.sonar.api.rules.RulePriority;
import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition;
@@ -37,6 +38,7 @@ import org.sonar.api.utils.System2;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.qualityprofile.ActiveRuleDto;
+import org.sonar.db.qualityprofile.ActiveRuleKey;
import org.sonar.db.qualityprofile.ActiveRuleParamDto;
import org.sonar.db.qualityprofile.OrgActiveRuleDto;
import org.sonar.db.qualityprofile.QProfileDto;
@@ -61,6 +63,7 @@ import static org.sonar.api.rules.RulePriority.MAJOR;
import static org.sonar.api.rules.RulePriority.MINOR;
import static org.sonar.db.qualityprofile.QualityProfileTesting.newRuleProfileDto;
import static org.sonar.server.qualityprofile.ActiveRuleInheritance.INHERITED;
+import static org.sonar.server.qualityprofile.ActiveRuleInheritance.OVERRIDES;
public class BuiltInQProfileUpdateImplTest {
@@ -272,6 +275,61 @@ public class BuiltInQProfileUpdateImplTest {
assertThatRuleIsActivated(grandchildProfile, rule, changes, rule.getSeverityString(), INHERITED, emptyMap());
}
+ // SONAR-14559
+ @Test
+ public void propagate_rule_update_to_descendant_active_rule() {
+ RuleDefinitionDto rule = db.rules().insert(r -> r.setLanguage("xoo").setSeverity(Severity.BLOCKER));
+
+ QProfileDto parentProfile = db.qualityProfiles().insert(p -> p.setLanguage(rule.getLanguage()).setIsBuiltIn(true));
+ activateRuleInDb(RulesProfileDto.from(parentProfile), rule, RulePriority.valueOf(Severity.MINOR), null);
+
+ QProfileDto childProfile = createChildProfile(parentProfile);
+ activateRuleInDb(RulesProfileDto.from(childProfile), rule, RulePriority.valueOf(Severity.MINOR), INHERITED);
+
+ BuiltInQualityProfilesDefinition.Context context = new BuiltInQualityProfilesDefinition.Context();
+ NewBuiltInQualityProfile newQp = context.createBuiltInQualityProfile(parentProfile.getName(), parentProfile.getLanguage());
+ newQp.activateRule(rule.getRepositoryKey(), rule.getRuleKey());
+ newQp.done();
+ BuiltInQProfile builtIn = builtInProfileRepository.create(context.profile(parentProfile.getLanguage(), parentProfile.getName()), rule);
+ List<ActiveRuleChange> changes = underTest.update(db.getSession(), builtIn, RulesProfileDto.from(parentProfile));
+
+ assertThat(changes).hasSize(2);
+
+ List<ActiveRuleDto> parentActiveRules = db.getDbClient().activeRuleDao().selectByRuleProfile(db.getSession(), RulesProfileDto.from(parentProfile));
+ assertThatRuleIsUpdated(parentActiveRules, rule, RulePriority.BLOCKER, null);
+
+ List<ActiveRuleDto> childActiveRules = db.getDbClient().activeRuleDao().selectByRuleProfile(db.getSession(), RulesProfileDto.from(childProfile));
+ assertThatRuleIsUpdated(childActiveRules, rule, RulePriority.BLOCKER, INHERITED);
+ }
+
+ @Test
+ public void propagate_rule_param_update_to_descendant_active_rule_params() {
+ RuleDefinitionDto rule = db.rules().insert(r -> r.setLanguage("xoo").setSeverity(Severity.BLOCKER));
+ RuleParamDto ruleParam = db.rules().insertRuleParam(rule, p -> p.setName("min").setDefaultValue("10"));
+
+ QProfileDto parentProfile = db.qualityProfiles().insert(p -> p.setLanguage(rule.getLanguage()).setIsBuiltIn(true));
+ ActiveRuleDto parentActiveRuleDto = activateRuleInDb(RulesProfileDto.from(parentProfile), rule,
+ RulePriority.valueOf(Severity.MINOR), null);
+ activateRuleParamInDb(parentActiveRuleDto, ruleParam, "20");
+
+ QProfileDto childProfile = createChildProfile(parentProfile);
+ ActiveRuleDto childActiveRuleDto = activateRuleInDb(RulesProfileDto.from(childProfile), rule,
+ RulePriority.valueOf(Severity.MINOR), INHERITED);
+ activateRuleParamInDb(childActiveRuleDto, ruleParam, "20");
+
+ BuiltInQualityProfilesDefinition.Context context = new BuiltInQualityProfilesDefinition.Context();
+ NewBuiltInQualityProfile newQp = context.createBuiltInQualityProfile(parentProfile.getName(), parentProfile.getLanguage());
+ newQp.activateRule(rule.getRepositoryKey(), rule.getRuleKey());
+ newQp.done();
+ BuiltInQProfile builtIn = builtInProfileRepository.create(context.profile(parentProfile.getLanguage(), parentProfile.getName()), rule);
+ List<ActiveRuleChange> changes = underTest.update(db.getSession(), builtIn, RulesProfileDto.from(parentProfile));
+
+ assertThat(changes).hasSize(2);
+
+ assertThatRuleHasParams(db, parentActiveRuleDto, tuple("min", "10"));
+ assertThatRuleHasParams(db, childActiveRuleDto, tuple("min", "10"));
+ }
+
@Test
public void do_not_load_descendants_if_no_changes() {
RuleDefinitionDto rule = db.rules().insert(r -> r.setLanguage("xoo"));
@@ -380,15 +438,27 @@ public class BuiltInQProfileUpdateImplTest {
assertThat(activeRule.getUpdatedAt()).isEqualTo(NOW);
}
- private static void assertThatRuleIsUpdated(List<ActiveRuleDto> activeRules, RuleDefinitionDto rule, RulePriority severity) {
+ private static void assertThatRuleIsUpdated(List<ActiveRuleDto> activeRules, RuleDefinitionDto rule, RulePriority severity, @Nullable ActiveRuleInheritance expectedInheritance) {
ActiveRuleDto activeRule = findRule(activeRules, rule).get();
- assertThat(activeRule.getInheritance()).isNull();
+ if (expectedInheritance != null) {
+ assertThat(activeRule.getInheritance()).isEqualTo(expectedInheritance.name());
+ } else {
+ assertThat(activeRule.getInheritance()).isNull();
+ }
assertThat(activeRule.getSeverityString()).isEqualTo(severity.name());
assertThat(activeRule.getCreatedAt()).isEqualTo(PAST);
assertThat(activeRule.getUpdatedAt()).isEqualTo(NOW);
}
+ private static void assertThatRuleIsUpdated(List<ActiveRuleDto> activeRules, RuleDefinitionDto rule, RulePriority severity) {
+ assertThatRuleIsUpdated(activeRules, rule, severity, null);
+ }
+
+ private static void assertThatRuleIsUpdated(ActiveRuleDto activeRules, RuleDefinitionDto rule, RulePriority severity, @Nullable ActiveRuleInheritance expectedInheritance) {
+ assertThatRuleIsUpdated(singletonList(activeRules), rule, severity, expectedInheritance);
+ }
+
private static void assertThatRuleIsUntouched(List<ActiveRuleDto> activeRules, RuleDefinitionDto rule, RulePriority severity) {
ActiveRuleDto activeRule = findRule(activeRules, rule).get();
@@ -432,14 +502,31 @@ public class BuiltInQProfileUpdateImplTest {
.findFirst();
}
- private void activateRuleInDb(RulesProfileDto profile, RuleDefinitionDto rule, RulePriority severity) {
+ private ActiveRuleDto activateRuleInDb(RulesProfileDto profile, RuleDefinitionDto rule, RulePriority severity) {
+ return activateRuleInDb(profile, rule, severity, null);
+ }
+
+ private ActiveRuleDto activateRuleInDb(RulesProfileDto ruleProfile, RuleDefinitionDto rule, RulePriority severity, @Nullable ActiveRuleInheritance inheritance) {
ActiveRuleDto dto = new ActiveRuleDto()
- .setProfileUuid(profile.getUuid())
+ .setKey(ActiveRuleKey.of(ruleProfile, RuleKey.of(rule.getRepositoryKey(), rule.getRuleKey())))
+ .setProfileUuid(ruleProfile.getUuid())
.setSeverity(severity.name())
.setRuleUuid(rule.getUuid())
+ .setInheritance(inheritance != null ? inheritance.name() : null)
.setCreatedAt(PAST)
.setUpdatedAt(PAST);
db.getDbClient().activeRuleDao().insert(db.getSession(), dto);
db.commit();
+ return dto;
+ }
+
+ private void activateRuleParamInDb(ActiveRuleDto activeRuleDto, RuleParamDto ruleParamDto, String value) {
+ ActiveRuleParamDto dto = new ActiveRuleParamDto()
+ .setActiveRuleUuid(activeRuleDto.getUuid())
+ .setRulesParameterUuid(ruleParamDto.getUuid())
+ .setKey(ruleParamDto.getName())
+ .setValue(value);
+ db.getDbClient().activeRuleDao().insertParam(db.getSession(), activeRuleDto, dto);
+ db.commit();
}
}
diff --git a/server/sonar-webserver-auth/src/test/java/org/sonar/server/qualityprofile/RuleActivatorTest.java b/server/sonar-webserver-auth/src/test/java/org/sonar/server/qualityprofile/RuleActivatorTest.java
new file mode 100644
index 00000000000..a36173fa87b
--- /dev/null
+++ b/server/sonar-webserver-auth/src/test/java/org/sonar/server/qualityprofile/RuleActivatorTest.java
@@ -0,0 +1,207 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.qualityprofile;
+
+import com.google.common.collect.ImmutableMap;
+import java.util.List;
+import javax.annotation.Nullable;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.impl.utils.TestSystem2;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rule.Severity;
+import org.sonar.api.rules.RulePriority;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbSession;
+import org.sonar.db.DbTester;
+import org.sonar.db.qualityprofile.ActiveRuleDto;
+import org.sonar.db.qualityprofile.ActiveRuleKey;
+import org.sonar.db.qualityprofile.ActiveRuleParamDto;
+import org.sonar.db.qualityprofile.QProfileDto;
+import org.sonar.db.qualityprofile.RulesProfileDto;
+import org.sonar.db.rule.RuleDefinitionDto;
+import org.sonar.db.rule.RuleParamDto;
+import org.sonar.server.qualityprofile.DescendantProfilesSupplier.Result;
+import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.util.IntegerTypeValidation;
+import org.sonar.server.util.StringTypeValidation;
+import org.sonar.server.util.TypeValidations;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.emptyList;
+import static java.util.Collections.singletonList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.server.qualityprofile.ActiveRuleInheritance.INHERITED;
+import static org.sonar.server.qualityprofile.ActiveRuleInheritance.OVERRIDES;
+
+/**
+ * Class org.sonar.server.qualityprofile.RuleActivator is mostly covered in
+ * org.sonar.server.qualityprofile.BuiltInQProfileUpdateImplTest
+ */
+public class RuleActivatorTest {
+ @Rule
+ public final DbTester db = DbTester.create();
+
+ @Rule
+ public final UserSessionRule userSession = UserSessionRule.standalone();
+
+ private static final long NOW = 1_000;
+ private static final long PAST = NOW - 100;
+ private final System2 system2 = new TestSystem2().setNow(NOW);
+ private final TypeValidations typeValidations = new TypeValidations(asList(new StringTypeValidation(), new IntegerTypeValidation()));
+
+ private final RuleActivator underTest = new RuleActivator(system2, db.getDbClient(), typeValidations, userSession);
+
+ @Test
+ public void reset_overridden_active_rule() {
+ RuleDefinitionDto rule = db.rules().insert(r -> r.setLanguage("xoo").setSeverity(Severity.BLOCKER));
+ RuleParamDto ruleParam = db.rules().insertRuleParam(rule, p -> p.setName("min").setDefaultValue("10"));
+
+ QProfileDto parentProfile = db.qualityProfiles().insert(p -> p.setLanguage(rule.getLanguage()).setIsBuiltIn(true));
+ ActiveRuleDto parentActiveRuleDto = activateRuleInDb(RulesProfileDto.from(parentProfile), rule,
+ RulePriority.valueOf(Severity.BLOCKER), null);
+ ActiveRuleParamDto parentActiveRuleParam = activateRuleParamInDb(parentActiveRuleDto, ruleParam, "10");
+
+ QProfileDto childProfile = createChildProfile(parentProfile);
+ ActiveRuleDto childActiveRuleDto = activateRuleInDb(RulesProfileDto.from(childProfile), rule,
+ RulePriority.valueOf(Severity.MINOR), OVERRIDES);
+ ActiveRuleParamDto childActiveRuleParam = activateRuleParamInDb(childActiveRuleDto, ruleParam, "15");
+
+ DbSession session = db.getSession();
+ RuleActivation resetRequest = RuleActivation.createReset(rule.getUuid());
+ RuleActivationContext context = new RuleActivationContext.Builder()
+ .setProfiles(asList(parentProfile, childProfile))
+ .setBaseProfile(RulesProfileDto.from(childProfile))
+ .setDate(NOW)
+ .setDescendantProfilesSupplier((profiles, ruleUuids) -> new Result(emptyList(), emptyList(), emptyList()))
+ .setRules(singletonList(rule))
+ .setRuleParams(singletonList(ruleParam))
+ .setActiveRules(asList(parentActiveRuleDto, childActiveRuleDto))
+ .setActiveRuleParams(asList(parentActiveRuleParam, childActiveRuleParam))
+ .build();
+
+ List<ActiveRuleChange> result = underTest.activate(session, resetRequest, context);
+
+ assertThat(result).hasSize(1);
+ assertThat(result.get(0).getParameters()).containsEntry("min", "10");
+ assertThat(result.get(0).getSeverity()).isEqualTo(Severity.BLOCKER);
+ assertThat(result.get(0).getInheritance()).isEqualTo(ActiveRuleInheritance.INHERITED);
+ }
+
+ @Test
+ public void request_new_severity_and_param_for_child_rule() {
+ RuleDefinitionDto rule = db.rules().insert(r -> r.setLanguage("xoo").setSeverity(Severity.BLOCKER));
+ RuleParamDto ruleParam = db.rules().insertRuleParam(rule, p -> p.setName("min").setDefaultValue("10"));
+
+ QProfileDto parentProfile = db.qualityProfiles().insert(p -> p.setLanguage(rule.getLanguage()).setIsBuiltIn(true));
+ ActiveRuleDto parentActiveRuleDto = activateRuleInDb(RulesProfileDto.from(parentProfile), rule,
+ RulePriority.valueOf(Severity.BLOCKER), null);
+ ActiveRuleParamDto parentActiveRuleParam = activateRuleParamInDb(parentActiveRuleDto, ruleParam, "10");
+
+ QProfileDto childProfile = createChildProfile(parentProfile);
+ ActiveRuleDto childActiveRuleDto = activateRuleInDb(RulesProfileDto.from(childProfile), rule,
+ RulePriority.valueOf(Severity.BLOCKER), INHERITED);
+ ActiveRuleParamDto childActiveRuleParam = activateRuleParamInDb(childActiveRuleDto, ruleParam, "10");
+
+ DbSession session = db.getSession();
+ RuleActivation resetRequest = RuleActivation.create(rule.getUuid(), Severity.MINOR, ImmutableMap.of("min", "15"));
+ RuleActivationContext context = new RuleActivationContext.Builder()
+ .setProfiles(asList(parentProfile, childProfile))
+ .setBaseProfile(RulesProfileDto.from(childProfile))
+ .setDate(NOW)
+ .setDescendantProfilesSupplier((profiles, ruleUuids) -> new Result(emptyList(), emptyList(), emptyList()))
+ .setRules(singletonList(rule))
+ .setRuleParams(singletonList(ruleParam))
+ .setActiveRules(asList(parentActiveRuleDto, childActiveRuleDto))
+ .setActiveRuleParams(asList(parentActiveRuleParam, childActiveRuleParam))
+ .build();
+
+ List<ActiveRuleChange> result = underTest.activate(session, resetRequest, context);
+
+ assertThat(result).hasSize(1);
+ assertThat(result.get(0).getParameters()).containsEntry("min", "15");
+ assertThat(result.get(0).getSeverity()).isEqualTo(Severity.MINOR);
+ assertThat(result.get(0).getInheritance()).isEqualTo(OVERRIDES);
+ }
+
+ @Test
+ public void set_severity_and_param_for_child_rule_when_activating() {
+ RuleDefinitionDto rule = db.rules().insert(r -> r.setLanguage("xoo").setSeverity(Severity.BLOCKER));
+ RuleParamDto ruleParam = db.rules().insertRuleParam(rule, p -> p.setName("min").setDefaultValue("10"));
+
+ QProfileDto parentProfile = db.qualityProfiles().insert(p -> p.setLanguage(rule.getLanguage()).setIsBuiltIn(true));
+
+ QProfileDto childProfile = createChildProfile(parentProfile);
+
+ DbSession session = db.getSession();
+ RuleActivation resetRequest = RuleActivation.create(rule.getUuid());
+ RuleActivationContext context = new RuleActivationContext.Builder()
+ .setProfiles(asList(parentProfile, childProfile))
+ .setBaseProfile(RulesProfileDto.from(childProfile))
+ .setDate(NOW)
+ .setDescendantProfilesSupplier((profiles, ruleUuids) -> new Result(emptyList(), emptyList(), emptyList()))
+ .setRules(singletonList(rule))
+ .setRuleParams(singletonList(ruleParam))
+ .setActiveRules(emptyList())
+ .setActiveRuleParams(emptyList())
+ .build();
+
+ List<ActiveRuleChange> result = underTest.activate(session, resetRequest, context);
+
+ assertThat(result).hasSize(1);
+ assertThat(result.get(0).getParameters()).containsEntry("min", "10");
+ assertThat(result.get(0).getSeverity()).isEqualTo(Severity.BLOCKER);
+ assertThat(result.get(0).getInheritance()).isNull();
+ }
+
+
+ private ActiveRuleDto activateRuleInDb(RulesProfileDto ruleProfile, RuleDefinitionDto rule, RulePriority severity, @Nullable ActiveRuleInheritance inheritance) {
+ ActiveRuleDto dto = new ActiveRuleDto()
+ .setKey(ActiveRuleKey.of(ruleProfile, RuleKey.of(rule.getRepositoryKey(), rule.getRuleKey())))
+ .setProfileUuid(ruleProfile.getUuid())
+ .setSeverity(severity.name())
+ .setRuleUuid(rule.getUuid())
+ .setInheritance(inheritance != null ? inheritance.name() : null)
+ .setCreatedAt(PAST)
+ .setUpdatedAt(PAST);
+ db.getDbClient().activeRuleDao().insert(db.getSession(), dto);
+ db.commit();
+ return dto;
+ }
+
+ private ActiveRuleParamDto activateRuleParamInDb(ActiveRuleDto activeRuleDto, RuleParamDto ruleParamDto, String value) {
+ ActiveRuleParamDto dto = new ActiveRuleParamDto()
+ .setActiveRuleUuid(activeRuleDto.getUuid())
+ .setRulesParameterUuid(ruleParamDto.getUuid())
+ .setKey(ruleParamDto.getName())
+ .setValue(value);
+ db.getDbClient().activeRuleDao().insertParam(db.getSession(), activeRuleDto, dto);
+ db.commit();
+ return dto;
+ }
+
+ private QProfileDto createChildProfile(QProfileDto parent) {
+ return db.qualityProfiles().insert(p -> p
+ .setLanguage(parent.getLanguage())
+ .setParentKee(parent.getKee())
+ .setName("Child of " + parent.getName()))
+ .setIsBuiltIn(false);
+ }
+}