aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-server
diff options
context:
space:
mode:
Diffstat (limited to 'server/sonar-server')
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivator.java8
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RuleActivatorMediumTest.java810
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RuleActivatorTest.java967
3 files changed, 975 insertions, 810 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivator.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivator.java
index c525b821737..ee553bdbd57 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivator.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivator.java
@@ -20,7 +20,6 @@
package org.sonar.server.qualityprofile;
import com.google.common.base.Splitter;
-import com.google.common.collect.Lists;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
@@ -83,7 +82,7 @@ public class RuleActivator {
private List<ActiveRuleChange> doActivate(DbSession dbSession, RuleActivation activation, RuleActivatorContext context) {
context.verifyForActivation();
- List<ActiveRuleChange> changes = Lists.newArrayList();
+ List<ActiveRuleChange> changes = new ArrayList<>();
ActiveRuleChange change;
boolean stopPropagation = false;
@@ -433,6 +432,11 @@ public class RuleActivator {
}
public List<ActiveRuleChange> setParent(DbSession dbSession, QProfileDto profile, @Nullable QProfileDto parent) {
+ checkRequest(
+ parent == null || profile.getLanguage().equals(parent.getLanguage()),
+ "Cannot set the profile '%s' as the parent of profile '%s' since their languages differ ('%s' != '%s')",
+ parent != null ? parent.getKee() : "", profile.getKee(), parent != null ? parent.getLanguage() : "", profile.getLanguage());
+
List<ActiveRuleChange> changes = new ArrayList<>();
if (parent == null) {
// unset if parent is defined, else nothing to do
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RuleActivatorMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RuleActivatorMediumTest.java
index be62199bdb6..fbab477c55e 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RuleActivatorMediumTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RuleActivatorMediumTest.java
@@ -25,24 +25,6 @@ public class RuleActivatorMediumTest {
// static final RuleKey TEMPLATE_RULE_KEY = RuleKey.of("xoo", "template1");
// static final RuleKey CUSTOM_RULE_KEY = RuleKey.of("xoo", "custom1");
//
-// @ClassRule
-// public static ServerTester tester = new ServerTester().withEsIndexes();
-//
-// @Rule
-// public UserSessionRule userSessionRule = UserSessionRule.forServerTester(tester);
-//
-// DbClient db;
-// DbSession dbSession;
-//
-// RuleActivator ruleActivator;
-//
-// RuleIndexer ruleIndexer;
-//
-// ActiveRuleIndexer activeRuleIndexer;
-//
-// QProfileDto profileDto;
-// private OrganizationDto organization;
-//
// @Before
// public void before() {
// tester.clearDbAndIndexes();
@@ -96,260 +78,15 @@ public class RuleActivatorMediumTest {
// dbSession.close();
// }
//
-// @Test
-// public void activate() {
-// RuleActivation activation = new RuleActivation(XOO_X1);
-// activation.setSeverity(BLOCKER);
-// activation.setParameter("max", "7");
-// activation.setParameter("min", "3");
-// List<ActiveRuleChange> changes = ruleActivator.activate(dbSession, activation, XOO_P1_KEY);
-// dbSession.commit();
-// dbSession.clearCache();
-//
-// assertThat(countActiveRules(XOO_P1_KEY)).isEqualTo(1);
-// verifyHasActiveRuleInDb(ActiveRuleKey.of(XOO_P1_KEY, XOO_X1), BLOCKER, null,
-// ImmutableMap.of("max", "7", "min", "3"));
-// assertThat(changes).hasSize(1);
-// assertThat(changes.get(0).getType()).isEqualTo(ActiveRuleChange.Type.ACTIVATED);
-// }
-//
-// @Test
-// public void automatic_activation_does_not_update_intended_column() {
-// RuleActivation activation = new RuleActivation(XOO_X1);
-// activation.setSeverity(BLOCKER);
-// activation.setParameter("max", "7");
-// activation.setParameter("min", "3");
-// List<ActiveRuleChange> changes = ruleActivator.activate(dbSession, activation, XOO_P1_KEY);
-// dbSession.commit();
-// dbSession.clearCache();
-// userSessionRule.anonymous();
-//
-// assertThat(countActiveRules(XOO_P1_KEY)).isEqualTo(1);
-// verifyHasActiveRuleInDb(ActiveRuleKey.of(XOO_P1_KEY, XOO_X1), BLOCKER, null,
-// ImmutableMap.of("max", "7", "min", "3"));
-// assertThat(changes).hasSize(1);
-// assertThat(changes.get(0).getType()).isEqualTo(ActiveRuleChange.Type.ACTIVATED);
-// assertProfileHasBeenUpdatedAutomatically(XOO_P1_KEY);
-// }
-//
-// @Test
-// public void activate_with_profile_dto() {
-// RuleActivation activation = new RuleActivation(XOO_X1);
-// activation.setSeverity(BLOCKER);
-// activation.setParameter("max", "7");
-// activation.setParameter("min", "3");
-// userSessionRule.logIn().setRoot();
-// List<ActiveRuleChange> changes = ruleActivator.activate(dbSession, activation, profileDto);
-// dbSession.commit();
-// dbSession.clearCache();
-//
-// assertThat(countActiveRules(XOO_P1_KEY)).isEqualTo(1);
-// verifyHasActiveRuleInDb(ActiveRuleKey.of(XOO_P1_KEY, XOO_X1), BLOCKER, null,
-// ImmutableMap.of("max", "7", "min", "3"));
-// assertThat(changes).hasSize(1);
-// assertThat(changes.get(0).getType()).isEqualTo(ActiveRuleChange.Type.ACTIVATED);
-// assertProfileHasBeenUpdatedManually(profileDto.getKee());
-// }
-//
-// @Test
-// public void activate_with_default_severity_and_parameter() {
-// activate(new RuleActivation(XOO_X1), XOO_P1_KEY);
-//
-// assertThat(countActiveRules(XOO_P1_KEY)).isEqualTo(1);
-// verifyHasActiveRuleInDb(ActiveRuleKey.of(XOO_P1_KEY, XOO_X1), MINOR, null,
-// ImmutableMap.of("max", "10"));
-// }
-//
-// /**
-// * SONAR-5841
-// */
-// @Test
-// public void activate_with_empty_parameter_having_no_default_value() {
-// activate(new RuleActivation(XOO_X1)
-// .setParameter("min", ""),
-// XOO_P1_KEY);
-//
-// assertThat(countActiveRules(XOO_P1_KEY)).isEqualTo(1);
-// verifyHasActiveRuleInDb(ActiveRuleKey.of(XOO_P1_KEY, XOO_X1), MINOR, null,
-// // Max should be set to default value, min has no value it should be ignored
-// ImmutableMap.of("max", "10"));
-// }
-//
-// /**
-// * SONAR-5841
-// */
-// @Test
-// public void activate_with_empty_parameters() {
-// activate(new RuleActivation(XOO_X1)
-// .setParameters(ImmutableMap.of("max", "", "min", "")),
-// XOO_P1_KEY);
-//
-// assertThat(countActiveRules(XOO_P1_KEY)).isEqualTo(1);
-// // Max should be set to default value, min has not value it should be ignored
-// verifyHasActiveRuleInDb(ActiveRuleKey.of(XOO_P1_KEY, XOO_X1), MINOR, null,
-// ImmutableMap.of("max", "10"));
-// }
-//
-// /**
-// * SONAR-5840
-// */
-// @Test
-// public void activate_rule_with_negative_integer_value_on_parameter_having_no_default_value() {
-// activate(new RuleActivation(XOO_X1)
-// .setParameter("min", "-10"),
-// XOO_P1_KEY);
-//
-// assertThat(countActiveRules(XOO_P1_KEY)).isEqualTo(1);
-// // Max should be set to default value, min should be set to -10
-// verifyHasActiveRuleInDb(ActiveRuleKey.of(XOO_P1_KEY, XOO_X1), MINOR, null,
-// ImmutableMap.of("max", "10", "min", "-10"));
-// }
-//
-// @Test
-// public void activation_ignores_unsupported_parameters() {
-// RuleActivation activation = new RuleActivation(XOO_X1);
-// activation.setParameter("xxx", "yyy");
-// activate(activation, XOO_P1_KEY);
-//
-// assertThat(countActiveRules(XOO_P1_KEY)).isEqualTo(1);
-// verifyHasActiveRuleInDb(ActiveRuleKey.of(XOO_P1_KEY, XOO_X1), MINOR, null, ImmutableMap.of("max", "10"));
-// }
-//
-// @Test
-// public void update_activation_severity_and_parameters() {
-// // initial activation
-// RuleActivation activation = new RuleActivation(XOO_X1);
-// activation.setSeverity(BLOCKER);
-// activate(activation, XOO_P1_KEY);
-//
-// // update
-// RuleActivation update = new RuleActivation(XOO_X1);
-// update.setSeverity(CRITICAL);
-// update.setParameter("max", "42");
-// List<ActiveRuleChange> changes = activate(update, XOO_P1_KEY);
-//
-// assertThat(countActiveRules(XOO_P1_KEY)).isEqualTo(1);
-// verifyHasActiveRuleInDb(ActiveRuleKey.of(XOO_P1_KEY, XOO_X1), CRITICAL, null, ImmutableMap.of("max", "42"));
-// assertThat(changes).hasSize(1);
-// assertThat(changes.get(0).getType()).isEqualTo(ActiveRuleChange.Type.UPDATED);
-// }
-//
-// @Test
-// public void update_activation_with_parameter_without_default_value() {
-// // initial activation -> param "max" has a default value
-// RuleActivation activation = new RuleActivation(XOO_X1);
-// activation.setSeverity(BLOCKER);
-// activate(activation, XOO_P1_KEY);
-// verifyHasActiveRuleInDb(ActiveRuleKey.of(XOO_P1_KEY, XOO_X1), BLOCKER, null,
-// ImmutableMap.of("max", "10"));
-//
-// // update param "min", which has no default value
-// RuleActivation update = new RuleActivation(XOO_X1);
-// update.setParameter("min", "3");
-// List<ActiveRuleChange> changes = activate(update, XOO_P1_KEY);
-// assertThat(countActiveRules(XOO_P1_KEY)).isEqualTo(1);
-// verifyHasActiveRuleInDb(ActiveRuleKey.of(XOO_P1_KEY, XOO_X1), BLOCKER, null,
-// ImmutableMap.of("min", "3", "max", "10"));
-// assertThat(changes).hasSize(1);
-// assertThat(changes.get(0).getType()).isEqualTo(ActiveRuleChange.Type.UPDATED);
-// }
-//
-// @Test
-// public void update_activation_remove_parameter_value_having_default_value() {
-// // initial activation
-// activate(new RuleActivation(XOO_X1).setSeverity(BLOCKER).setParameter("max", "20"), XOO_P1_KEY);
-//
-// // update
-// activate(new RuleActivation(XOO_X1).setParameter("max", null), XOO_P1_KEY);
-//
-// verifyHasActiveRuleInDb(ActiveRuleKey.of(XOO_P1_KEY, XOO_X1), BLOCKER, null, ImmutableMap.of("max", "10"));
-// }
-//
-// @Test
-// public void update_activation_remove_parameter_value_without_default_value() {
-// // initial activation -> param "min" has a no default value
-// activate(new RuleActivation(XOO_X1).setSeverity(BLOCKER).setParameter("min", "5"), XOO_P1_KEY);
-//
-// // update param "min" with empty value
-// activate(new RuleActivation(XOO_X1).setParameter("min", null), XOO_P1_KEY);
-//
-// verifyHasActiveRuleInDb(ActiveRuleKey.of(XOO_P1_KEY, XOO_X1), BLOCKER, null, ImmutableMap.of("max", "10"));
-// }
-//
-// @Test
-// public void update_activation_but_new_parameter() {
-// // initial activation
-// ActiveRuleKey activeRuleKey = ActiveRuleKey.of(XOO_P1_KEY, XOO_X1);
-// RuleActivation activation = new RuleActivation(XOO_X1);
-// activation.setSeverity(BLOCKER);
-// activate(activation, XOO_P1_KEY);
-//
-// assertThat(db.activeRuleDao().selectParamByKeyAndName(activeRuleKey, "max", dbSession)).isNotNull();
-// // FIXME db.activeRuleDao().deleteParamByKeyAndName(dbSession, activeRuleKey, "max");
-// dbSession.commit();
-// assertThat(db.activeRuleDao().selectParamByKeyAndName(activeRuleKey, "max", dbSession)).isNull();
-// dbSession.clearCache();
-//
-// // update
-// RuleActivation update = new RuleActivation(XOO_X1);
-// update.setSeverity(CRITICAL);
-// update.setParameter("max", "42");
-// // contrary to activerule, the param 'max' is supposed to be inserted but not updated
-// activate(update, XOO_P1_KEY);
//
-// assertThat(countActiveRules(XOO_P1_KEY)).isEqualTo(1);
-// verifyHasActiveRuleInDb(activeRuleKey, CRITICAL, null, ImmutableMap.of("max", "42"));
-// }
-//
-// @Test
-// public void ignore_activation_without_changes() {
-// // initial activation
-// RuleActivation activation = new RuleActivation(XOO_X1);
-// activation.setSeverity(BLOCKER);
-// activate(activation, XOO_P1_KEY);
//
-// // update with exactly the same severity and params
-// RuleActivation update = new RuleActivation(XOO_X1);
-// update.setSeverity(BLOCKER);
-// List<ActiveRuleChange> changes = activate(update, XOO_P1_KEY);
-// assertThat(changes).isEmpty();
-// }
//
-// @Test
-// public void do_not_change_severity_and_params_if_unset_and_already_activated() {
-// // initial activation
-// ActiveRuleKey activeRuleKey = ActiveRuleKey.of(XOO_P1_KEY, XOO_X1);
-// RuleActivation activation = new RuleActivation(XOO_X1);
-// activation.setSeverity(BLOCKER);
-// activation.setParameter("max", "7");
-// activate(activation, XOO_P1_KEY);
//
-// // update without any severity or params => keep
-// RuleActivation update = new RuleActivation(XOO_X1);
-// activate(update, XOO_P1_KEY);
//
-// assertThat(countActiveRules(XOO_P1_KEY)).isEqualTo(1);
-// verifyHasActiveRuleInDb(activeRuleKey, BLOCKER, null, ImmutableMap.of("max", "7"));
-// }
//
-// @Test
-// public void revert_activation_to_default_severity_and_parameters() {
-// // initial activation
-// ActiveRuleKey activeRuleKey = ActiveRuleKey.of(XOO_P1_KEY, XOO_X1);
-// RuleActivation activation = new RuleActivation(XOO_X1);
-// activation.setSeverity(BLOCKER);
-// activation.setParameter("max", "7");
-// activation.setParameter("min", "3");
-// activate(activation, XOO_P1_KEY);
//
-// // update without any severity or params = reset
-// RuleActivation update = new RuleActivation(XOO_X1).setReset(true);
-// activate(update, XOO_P1_KEY);
-// assertThat(countActiveRules(XOO_P1_KEY)).isEqualTo(1);
-// verifyHasActiveRuleInDb(activeRuleKey, MINOR, null,
-// // only default values
-// ImmutableMap.of("max", "10"));
-// }
+
+
//
// @Test
// public void ignore_parameters_when_activating_custom_rule() {
@@ -367,126 +104,6 @@ public class RuleActivatorMediumTest {
// verifyHasActiveRuleInDb(activeRuleKey, MINOR, null, ImmutableMap.of("format", "txt"));
// }
//
-// @Test
-// public void fail_to_activate_if_template() {
-// RuleActivation activation = new RuleActivation(TEMPLATE_RULE_KEY);
-//
-// try {
-// activate(activation, XOO_P1_KEY);
-// fail();
-// } catch (BadRequestException e) {
-// assertThat(e).hasMessage("Rule template can't be activated on a Quality profile: xoo:template1");
-// verifyZeroActiveRules(XOO_P1_KEY);
-// }
-// }
-//
-// @Test
-// public void fail_to_activate_if_different_languages() {
-// // profile and rule have different languages
-// RuleActivation activation = new RuleActivation(RuleKey.of("squid", "j1"));
-//
-// try {
-// activate(activation, XOO_P1_KEY);
-// fail();
-// } catch (BadRequestException e) {
-// assertThat(e).hasMessage("Rule squid:j1 and profile XOO_P1 have different languages");
-// verifyZeroActiveRules(XOO_P1_KEY);
-// }
-// }
-//
-// @Test
-// public void fail_to_activate_if_unknown_rule() {
-// // profile and rule have different languages
-// RuleActivation activation = new RuleActivation(RuleKey.of("xoo", "x3"));
-//
-// try {
-// activate(activation, XOO_P1_KEY);
-// fail();
-// } catch (BadRequestException e) {
-// assertThat(e).hasMessage("Rule not found: xoo:x3");
-// verifyZeroActiveRules(XOO_P1_KEY);
-// }
-// }
-//
-// @Test
-// public void fail_to_activate_if_rule_with_removed_status() {
-// RuleDefinitionDto ruleDto = db.ruleDao().selectOrFailDefinitionByKey(dbSession, XOO_X1);
-// ruleDto.setStatus(RuleStatus.REMOVED);
-// db.ruleDao().update(dbSession, ruleDto);
-// dbSession.commit();
-// dbSession.clearCache();
-//
-// RuleActivation activation = new RuleActivation(XOO_X1);
-//
-// try {
-// activate(activation, XOO_P1_KEY);
-// fail();
-// } catch (BadRequestException e) {
-// assertThat(e).hasMessage("Rule was removed: xoo:x1");
-// verifyZeroActiveRules(XOO_P1_KEY);
-// }
-// }
-//
-// @Test
-// public void fail_to_activate_if_unknown_profile() {
-// try {
-// activate(new RuleActivation(XOO_X1), "unknown");
-// fail();
-// } catch (BadRequestException e) {
-// assertThat(e).hasMessage("Quality profile not found: unknown");
-// }
-// }
-//
-// @Test
-// public void fail_to_activate_if_invalid_parameter() {
-// RuleActivation activation = new RuleActivation(XOO_X1);
-// activation.setParameter("max", "foo");
-//
-// try {
-// activate(activation, XOO_P1_KEY);
-// fail();
-// } catch (BadRequestException e) {
-// assertThat(e.getMessage()).isEqualTo("Value 'foo' must be an integer.");
-// verifyZeroActiveRules(XOO_P1_KEY);
-// }
-// }
-//
-// @Test
-// public void deactivate() {
-// // activation
-// RuleActivation activation = new RuleActivation(XOO_X1);
-// activation.setSeverity(BLOCKER);
-// activation.setParameter("max", "7");
-// userSessionRule.logIn();
-// activate(activation, XOO_P1_KEY);
-//
-// // deactivation
-// ruleActivator.deactivateAndUpdateIndex(dbSession, ActiveRuleKey.of(XOO_P1_KEY, XOO_X1));
-//
-// verifyZeroActiveRules(XOO_P1_KEY);
-// assertProfileHasBeenUpdatedManually(XOO_P1_KEY);
-// }
-//
-// @Test
-// public void ignore_deactivation_if_rule_not_activated() {
-// // deactivation
-// ActiveRuleKey key = ActiveRuleKey.of(XOO_P1_KEY, XOO_X1);
-// ruleActivator.deactivateAndUpdateIndex(dbSession, key);
-//
-// verifyZeroActiveRules(XOO_P1_KEY);
-// }
-//
-// @Test
-// public void deactivation_fails_if_rule_not_found() {
-// ActiveRuleKey key = ActiveRuleKey.of(XOO_P1_KEY, RuleKey.of("xoo", "x3"));
-// try {
-// ruleActivator.deactivateAndUpdateIndex(dbSession, key);
-// fail();
-// } catch (BadRequestException e) {
-// assertThat(e).hasMessage("Rule not found: xoo:x3");
-// verifyZeroActiveRules(XOO_P1_KEY);
-// }
-// }
//
// @Test
// public void deactivation_fails_if_profile_not_found() {
@@ -499,351 +116,6 @@ public class RuleActivatorMediumTest {
// }
// }
//
-// @Test
-// public void allow_to_deactivate_removed_rule() {
-// // activation
-// RuleActivation activation = new RuleActivation(XOO_X1);
-// activate(activation, XOO_P1_KEY);
-//
-// // set rule as removed
-// RuleDefinitionDto rule = db.ruleDao().selectOrFailDefinitionByKey(dbSession, XOO_X1);
-// rule.setStatus(RuleStatus.REMOVED);
-// db.ruleDao().update(dbSession, rule);
-// dbSession.commit();
-// dbSession.clearCache();
-//
-// // deactivation
-// ruleActivator.deactivateAndUpdateIndex(dbSession, ActiveRuleKey.of(XOO_P1_KEY, XOO_X1));
-//
-// verifyZeroActiveRules(XOO_P1_KEY);
-// }
-//
-// // INHERITANCE OF PROFILES
-// @Test
-// public void activate_on_child_profile_but_not_on_parent() {
-// createChildProfiles();
-//
-// // activate on child profile, but not on root
-// RuleActivation activation = new RuleActivation(XOO_X1);
-// activation.setSeverity(BLOCKER);
-// activation.setParameter("max", "7");
-// activate(activation, XOO_P2_KEY);
-//
-// verifyZeroActiveRules(XOO_P1_KEY);
-// verifyOneActiveRuleInDb(XOO_P2_KEY, XOO_X1, BLOCKER, null, ImmutableMap.of("max", "7"));
-// verifyOneActiveRuleInDb(XOO_P3_KEY, XOO_X1, BLOCKER, INHERITED, ImmutableMap.of("max", "7"));
-//
-// // update severity on child
-// activation = new RuleActivation(XOO_X1);
-// activation.setSeverity(MINOR);
-// activation.setParameter("max", "77");
-// activate(activation, XOO_P2_KEY);
-//
-// verifyZeroActiveRules(XOO_P1_KEY);
-// verifyOneActiveRuleInDb(XOO_P2_KEY, XOO_X1, MINOR, null, ImmutableMap.of("max", "77"));
-// verifyOneActiveRuleInDb(XOO_P3_KEY, XOO_X1, MINOR, INHERITED, ImmutableMap.of("max", "77"));
-// }
-//
-// @Test
-// public void propagate_activation_on_child_profiles() {
-// createChildProfiles();
-//
-// // activate on root profile
-// RuleActivation activation = new RuleActivation(XOO_X1);
-// activation.setSeverity(BLOCKER);
-// activation.setParameter("max", "7");
-// List<ActiveRuleChange> changes = activate(activation, XOO_P1_KEY);
-//
-// assertThat(changes).hasSize(3);
-// verifyOneActiveRuleInDb(XOO_P1_KEY, XOO_X1, BLOCKER, null, ImmutableMap.of("max", "7"));
-// verifyOneActiveRuleInDb(XOO_P2_KEY, XOO_X1, BLOCKER, INHERITED, ImmutableMap.of("max", "7"));
-// verifyOneActiveRuleInDb(XOO_P3_KEY, XOO_X1, BLOCKER, INHERITED, ImmutableMap.of("max", "7"));
-// }
-//
-// @Test
-// public void propagate_activation_update_on_child_profiles() {
-// createChildProfiles();
-// userSessionRule.logIn();
-//
-// // activate on root profile
-// RuleActivation activation = new RuleActivation(XOO_X1);
-// activation.setSeverity(BLOCKER);
-// activation.setParameter("max", "7");
-// activate(activation, XOO_P1_KEY);
-// verifyOneActiveRuleInDb(XOO_P1_KEY, XOO_X1, BLOCKER, null, ImmutableMap.of("max", "7"));
-// verifyOneActiveRuleInDb(XOO_P2_KEY, XOO_X1, BLOCKER, INHERITED, ImmutableMap.of("max", "7"));
-// verifyOneActiveRuleInDb(XOO_P3_KEY, XOO_X1, BLOCKER, INHERITED, ImmutableMap.of("max", "7"));
-//
-// // update on parent
-// activation = new RuleActivation(XOO_X1);
-// activation.setSeverity(INFO);
-// activation.setParameter("max", "8");
-// activate(activation, XOO_P1_KEY);
-//
-// verifyOneActiveRuleInDb(XOO_P1_KEY, XOO_X1, INFO, null, ImmutableMap.of("max", "8"));
-// verifyOneActiveRuleInDb(XOO_P2_KEY, XOO_X1, INFO, INHERITED, ImmutableMap.of("max", "8"));
-// verifyOneActiveRuleInDb(XOO_P3_KEY, XOO_X1, INFO, INHERITED, ImmutableMap.of("max", "8"));
-//
-// // update on child -> propagate on grand child only
-// activation = new RuleActivation(XOO_X1);
-// activation.setSeverity(MINOR);
-// activation.setParameter("max", "9");
-// activate(activation, XOO_P2_KEY);
-//
-// verifyOneActiveRuleInDb(XOO_P1_KEY, XOO_X1, INFO, null, ImmutableMap.of("max", "8"));
-// verifyOneActiveRuleInDb(XOO_P2_KEY, XOO_X1, MINOR, OVERRIDES, ImmutableMap.of("max", "9"));
-// verifyOneActiveRuleInDb(XOO_P3_KEY, XOO_X1, MINOR, INHERITED, ImmutableMap.of("max", "9"));
-//
-// // update on grand child
-// activation = new RuleActivation(XOO_X1);
-// activation.setSeverity(BLOCKER);
-// activation.setParameter("max", "10");
-// activate(activation, XOO_P3_KEY);
-//
-// verifyOneActiveRuleInDb(XOO_P1_KEY, XOO_X1, INFO, null, ImmutableMap.of("max", "8"));
-// verifyOneActiveRuleInDb(XOO_P2_KEY, XOO_X1, MINOR, OVERRIDES, ImmutableMap.of("max", "9"));
-// verifyOneActiveRuleInDb(XOO_P3_KEY, XOO_X1, BLOCKER, OVERRIDES, ImmutableMap.of("max", "10"));
-//
-// assertProfileHasBeenUpdatedManually(XOO_P1_KEY);
-// assertProfileHasBeenUpdatedManually(XOO_P2_KEY);
-// assertProfileHasBeenUpdatedManually(XOO_P3_KEY);
-// }
-//
-// @Test
-// public void do_not_propagate_activation_update_on_child_overrides() {
-// createChildProfiles();
-//
-// // activate on root profile P1
-// RuleActivation activation = new RuleActivation(XOO_X1);
-// activation.setSeverity(INFO);
-// activation.setParameter("max", "7");
-// activate(activation, XOO_P1_KEY);
-// verifyOneActiveRuleInDb(XOO_P1_KEY, XOO_X1, INFO, null, ImmutableMap.of("max", "7"));
-// verifyOneActiveRuleInDb(XOO_P2_KEY, XOO_X1, INFO, INHERITED, ImmutableMap.of("max", "7"));
-// verifyOneActiveRuleInDb(XOO_P3_KEY, XOO_X1, INFO, INHERITED, ImmutableMap.of("max", "7"));
-//
-// // override on child P2
-// activation = new RuleActivation(XOO_X1);
-// activation.setSeverity(BLOCKER);
-// activation.setParameter("max", "8");
-// activate(activation, XOO_P2_KEY);
-// verifyOneActiveRuleInDb(XOO_P1_KEY, XOO_X1, INFO, null, ImmutableMap.of("max", "7"));
-// verifyOneActiveRuleInDb(XOO_P2_KEY, XOO_X1, BLOCKER, OVERRIDES, ImmutableMap.of("max", "8"));
-// verifyOneActiveRuleInDb(XOO_P3_KEY, XOO_X1, BLOCKER, INHERITED, ImmutableMap.of("max", "8"));
-//
-// // change on parent -> do not propagate on children because they're overriding values
-// activation = new RuleActivation(XOO_X1);
-// activation.setSeverity(CRITICAL);
-// activation.setParameter("max", "9");
-// activate(activation, XOO_P1_KEY);
-// verifyOneActiveRuleInDb(XOO_P1_KEY, XOO_X1, CRITICAL, null, ImmutableMap.of("max", "9"));
-// verifyOneActiveRuleInDb(XOO_P2_KEY, XOO_X1, BLOCKER, OVERRIDES, ImmutableMap.of("max", "8"));
-// verifyOneActiveRuleInDb(XOO_P3_KEY, XOO_X1, BLOCKER, INHERITED, ImmutableMap.of("max", "8"));
-//
-// // reset on parent (use default severity and params) -> do not propagate on children because they're overriding values
-// activation = new RuleActivation(XOO_X1).setReset(true);
-// activate(activation, XOO_P1_KEY);
-//
-// verifyOneActiveRuleInDb(XOO_P1_KEY, XOO_X1, MINOR, null, ImmutableMap.of("max", "10"));
-// verifyOneActiveRuleInDb(XOO_P2_KEY, XOO_X1, BLOCKER, OVERRIDES, ImmutableMap.of("max", "8"));
-// verifyOneActiveRuleInDb(XOO_P3_KEY, XOO_X1, BLOCKER, INHERITED, ImmutableMap.of("max", "8"));
-// }
-//
-// @Test
-// public void active_on_parent_a_rule_already_activated_on_child() {
-// createChildProfiles();
-//
-// // activate on child profile
-// RuleActivation activation = new RuleActivation(XOO_X1);
-// activation.setSeverity(INFO);
-// activation.setParameter("max", "7");
-// activate(activation, XOO_P2_KEY);
-// verifyZeroActiveRules(XOO_P1_KEY);
-// verifyOneActiveRuleInDb(XOO_P2_KEY, XOO_X1, INFO, null, ImmutableMap.of("max", "7"));
-// verifyOneActiveRuleInDb(XOO_P3_KEY, XOO_X1, INFO, INHERITED, ImmutableMap.of("max", "7"));
-//
-// // active the same rule on root profile -> mark the child profile as OVERRIDES
-// activation = new RuleActivation(XOO_X1);
-// activation.setSeverity(MAJOR);
-// activation.setParameter("max", "8");
-// activate(activation, XOO_P1_KEY);
-// verifyOneActiveRuleInDb(XOO_P1_KEY, XOO_X1, MAJOR, null, ImmutableMap.of("max", "8"));
-// verifyOneActiveRuleInDb(XOO_P2_KEY, XOO_X1, INFO, OVERRIDES, ImmutableMap.of("max", "7"));
-// verifyOneActiveRuleInDb(XOO_P3_KEY, XOO_X1, INFO, INHERITED, ImmutableMap.of("max", "7"));
-// }
-//
-// @Test
-// public void do_not_override_on_child_if_same_values() {
-// createChildProfiles();
-//
-// // activate on root profile
-// RuleActivation activation = new RuleActivation(XOO_X1);
-// activation.setSeverity(INFO);
-// activation.setParameter("max", "7");
-// activate(activation, XOO_P1_KEY);
-// verifyOneActiveRuleInDb(XOO_P1_KEY, XOO_X1, INFO, null, ImmutableMap.of("max", "7"));
-// verifyOneActiveRuleInDb(XOO_P2_KEY, XOO_X1, INFO, INHERITED, ImmutableMap.of("max", "7"));
-//
-// // override on child P2 with same severity and params -> do nothing (still INHERITED but not OVERRIDDEN)
-// activation = new RuleActivation(XOO_X1);
-// activation.setSeverity(INFO);
-// activation.setParameter("max", "7");
-// activate(activation, XOO_P2_KEY);
-// verifyOneActiveRuleInDb(XOO_P1_KEY, XOO_X1, INFO, null, ImmutableMap.of("max", "7"));
-// verifyOneActiveRuleInDb(XOO_P2_KEY, XOO_X1, INFO, INHERITED, ImmutableMap.of("max", "7"));
-// }
-//
-// @Test
-// public void propagate_deactivation_on_child_profiles() {
-// createChildProfiles();
-//
-// // activate on root profile
-// RuleActivation activation = new RuleActivation(XOO_X1);
-// activation.setSeverity(BLOCKER);
-// activation.setParameter("max", "7");
-// activate(activation, XOO_P1_KEY);
-// verifyOneActiveRuleInDb(XOO_P1_KEY, XOO_X1, BLOCKER, null, ImmutableMap.of("max", "7"));
-// verifyOneActiveRuleInDb(XOO_P2_KEY, XOO_X1, BLOCKER, INHERITED, ImmutableMap.of("max", "7"));
-// verifyOneActiveRuleInDb(XOO_P3_KEY, XOO_X1, BLOCKER, INHERITED, ImmutableMap.of("max", "7"));
-//
-// // deactivate on root
-// ruleActivator.deactivateAndUpdateIndex(dbSession, ActiveRuleKey.of(XOO_P1_KEY, XOO_X1));
-//
-// verifyZeroActiveRules(XOO_P1_KEY);
-// verifyZeroActiveRules(XOO_P2_KEY);
-// verifyZeroActiveRules(XOO_P3_KEY);
-// }
-//
-// @Test
-// public void propagate_deactivation_even_on_child_overrides() {
-// createChildProfiles();
-//
-// // activate on root profile
-// RuleActivation activation = new RuleActivation(XOO_X1);
-// activation.setSeverity(INFO);
-// activation.setParameter("max", "7");
-// activate(activation, XOO_P1_KEY);
-// verifyOneActiveRuleInDb(XOO_P1_KEY, XOO_X1, INFO, null, ImmutableMap.of("max", "7"));
-// verifyOneActiveRuleInDb(XOO_P2_KEY, XOO_X1, INFO, INHERITED, ImmutableMap.of("max", "7"));
-// verifyOneActiveRuleInDb(XOO_P3_KEY, XOO_X1, INFO, INHERITED, ImmutableMap.of("max", "7"));
-//
-// // override on child
-// activation = new RuleActivation(XOO_X1);
-// activation.setSeverity(BLOCKER);
-// activation.setParameter("max", "8");
-// activate(activation, XOO_P2_KEY);
-// verifyOneActiveRuleInDb(XOO_P1_KEY, XOO_X1, INFO, null, ImmutableMap.of("max", "7"));
-// verifyOneActiveRuleInDb(XOO_P2_KEY, XOO_X1, BLOCKER, OVERRIDES, ImmutableMap.of("max", "8"));
-// verifyOneActiveRuleInDb(XOO_P3_KEY, XOO_X1, BLOCKER, INHERITED, ImmutableMap.of("max", "8"));
-//
-// // deactivate on parent -> do not propagate on children because they're overriding values
-// ruleActivator.deactivateAndUpdateIndex(dbSession, ActiveRuleKey.of(XOO_P1_KEY, XOO_X1));
-// dbSession.clearCache();
-// verifyZeroActiveRules(XOO_P1_KEY);
-// verifyZeroActiveRules(XOO_P2_KEY);
-// verifyZeroActiveRules(XOO_P3_KEY);
-// }
-//
-// @Test
-// public void do_not_deactivate_inherited_or_overridden_rule() {
-// createChildProfiles();
-//
-// // activate on root profile
-// RuleActivation activation = new RuleActivation(XOO_X1);
-// activation.setSeverity(BLOCKER);
-// activation.setParameter("max", "7");
-// activate(activation, XOO_P1_KEY);
-// verifyOneActiveRuleInDb(XOO_P1_KEY, XOO_X1, BLOCKER, null, ImmutableMap.of("max", "7"));
-// verifyOneActiveRuleInDb(XOO_P2_KEY, XOO_X1, BLOCKER, INHERITED, ImmutableMap.of("max", "7"));
-// verifyOneActiveRuleInDb(XOO_P3_KEY, XOO_X1, BLOCKER, INHERITED, ImmutableMap.of("max", "7"));
-//
-// // try to deactivate on child
-// try {
-// ruleActivator.deactivateAndUpdateIndex(dbSession, ActiveRuleKey.of(XOO_P2_KEY, XOO_X1));
-// fail();
-// } catch (BadRequestException e) {
-// assertThat(e).hasMessage("Cannot deactivate inherited rule 'xoo:x1'");
-// }
-// }
-//
-// @Test
-// public void reset_child_profile() {
-// createChildProfiles();
-//
-// // activate on root profile
-// RuleActivation activation = new RuleActivation(XOO_X1);
-// activation.setSeverity(BLOCKER);
-// activation.setParameter("max", "7");
-// activate(activation, XOO_P1_KEY);
-// verifyOneActiveRuleInDb(XOO_P1_KEY, XOO_X1, BLOCKER, null, ImmutableMap.of("max", "7"));
-// verifyOneActiveRuleInDb(XOO_P2_KEY, XOO_X1, BLOCKER, INHERITED, ImmutableMap.of("max", "7"));
-// verifyOneActiveRuleInDb(XOO_P3_KEY, XOO_X1, BLOCKER, INHERITED, ImmutableMap.of("max", "7"));
-//
-// // override
-// activation = new RuleActivation(XOO_X1);
-// activation.setSeverity(INFO);
-// activation.setParameter("max", "10");
-// activate(activation, XOO_P2_KEY);
-// verifyOneActiveRuleInDb(XOO_P1_KEY, XOO_X1, BLOCKER, null, ImmutableMap.of("max", "7"));
-// verifyOneActiveRuleInDb(XOO_P2_KEY, XOO_X1, INFO, OVERRIDES, ImmutableMap.of("max", "10"));
-// verifyOneActiveRuleInDb(XOO_P3_KEY, XOO_X1, INFO, INHERITED, ImmutableMap.of("max", "10"));
-//
-// // reset -> remove overridden values
-// activation = new RuleActivation(XOO_X1).setReset(true);
-// activate(activation, XOO_P2_KEY);
-// verifyOneActiveRuleInDb(XOO_P1_KEY, XOO_X1, BLOCKER, null, ImmutableMap.of("max", "7"));
-// verifyOneActiveRuleInDb(XOO_P2_KEY, XOO_X1, BLOCKER, INHERITED, ImmutableMap.of("max", "7"));
-// verifyOneActiveRuleInDb(XOO_P3_KEY, XOO_X1, BLOCKER, INHERITED, ImmutableMap.of("max", "7"));
-// }
-//
-// @Test
-// public void reset_is_not_propagated_to_child_overrides() {
-// createChildProfiles();
-//
-// // activate on root profile
-// RuleActivation activation = new RuleActivation(XOO_X1);
-// activation.setSeverity(BLOCKER);
-// activation.setParameter("max", "7");
-// activate(activation, XOO_P1_KEY);
-// verifyOneActiveRuleInDb(XOO_P1_KEY, XOO_X1, BLOCKER, null, ImmutableMap.of("max", "7"));
-// verifyOneActiveRuleInDb(XOO_P2_KEY, XOO_X1, BLOCKER, INHERITED, ImmutableMap.of("max", "7"));
-// verifyOneActiveRuleInDb(XOO_P3_KEY, XOO_X1, BLOCKER, INHERITED, ImmutableMap.of("max", "7"));
-//
-// // override on child
-// activation = new RuleActivation(XOO_X1);
-// activation.setSeverity(INFO);
-// activation.setParameter("max", "10");
-// activate(activation, XOO_P2_KEY);
-// verifyOneActiveRuleInDb(XOO_P1_KEY, XOO_X1, BLOCKER, null, ImmutableMap.of("max", "7"));
-// verifyOneActiveRuleInDb(XOO_P2_KEY, XOO_X1, INFO, OVERRIDES, ImmutableMap.of("max", "10"));
-// verifyOneActiveRuleInDb(XOO_P3_KEY, XOO_X1, INFO, INHERITED, ImmutableMap.of("max", "10"));
-//
-// // override on grand child
-// activation = new RuleActivation(XOO_X1);
-// activation.setSeverity(MINOR);
-// activation.setParameter("max", "20");
-// activate(activation, XOO_P3_KEY);
-// verifyOneActiveRuleInDb(XOO_P1_KEY, XOO_X1, BLOCKER, null, ImmutableMap.of("max", "7"));
-// verifyOneActiveRuleInDb(XOO_P2_KEY, XOO_X1, INFO, OVERRIDES, ImmutableMap.of("max", "10"));
-// verifyOneActiveRuleInDb(XOO_P3_KEY, XOO_X1, MINOR, OVERRIDES, ImmutableMap.of("max", "20"));
-//
-// // reset child P2 -> keep the overridden grand-child P3
-// activation = new RuleActivation(XOO_X1).setReset(true);
-// activate(activation, XOO_P2_KEY);
-// verifyOneActiveRuleInDb(XOO_P1_KEY, XOO_X1, BLOCKER, null, ImmutableMap.of("max", "7"));
-// verifyOneActiveRuleInDb(XOO_P2_KEY, XOO_X1, BLOCKER, INHERITED, ImmutableMap.of("max", "7"));
-// verifyOneActiveRuleInDb(XOO_P3_KEY, XOO_X1, MINOR, OVERRIDES, ImmutableMap.of("max", "20"));
-// }
-//
-// @Test
-// public void ignore_reset_if_not_activated() {
-// createChildProfiles();
-// RuleActivation activation = new RuleActivation(XOO_X1).setReset(true);
-// activate(activation, XOO_P1_KEY);
-//
-// verifyZeroActiveRules(XOO_P1_KEY);
-// verifyZeroActiveRules(XOO_P2_KEY);
-// }
//
// @Test
// public void bulk_activation() {
@@ -892,84 +164,6 @@ public class RuleActivatorMediumTest {
// assertThat(result.countFailed()).isGreaterThan(0);
// }
//
-// @Test
-// public void set_and_unset_parent_profile() {
-// // x1 is activated on the "future parent" P1
-// RuleActivation activation = new RuleActivation(XOO_X1);
-// activation.setSeverity("MAJOR");
-// activate(activation, XOO_P1_KEY);
-// verifyOneActiveRuleInDb(XOO_P1_KEY, XOO_X1, MAJOR, null, ImmutableMap.of("max", "10"));
-//
-// // create profile P2 with x2
-// db.qualityProfileDao().insert(dbSession, QProfileTesting.newXooP2("org-123"));
-// activation = new RuleActivation(XOO_X2);
-// activation.setSeverity("MAJOR");
-// activate(activation, XOO_P2_KEY);
-//
-// // set parent -> child profile inherits rule x1 and still has x2
-// ruleActivator.setParent(dbSession, selectProfile(XOO_P2_KEY), selectProfile(XOO_P1_KEY));
-// dbSession.clearCache();
-// assertThat(db.qualityProfileDao().selectByUuid(dbSession, XOO_P2_KEY).getParentKee()).isEqualTo(XOO_P1_KEY);
-//
-// verifyHasActiveRuleInDbAndIndex(ActiveRuleKey.of(XOO_P2_KEY, XOO_X1), MAJOR, INHERITED, ImmutableMap.of("max", "10"));
-// verifyHasActiveRuleInDbAndIndex(ActiveRuleKey.of(XOO_P2_KEY, XOO_X2), MAJOR, null, Collections.emptyMap());
-//
-// // unset parent
-// dbSession.clearCache();
-// ruleActivator.setParent(dbSession, selectProfile(XOO_P2_KEY), null);
-// assertThat(countActiveRules(XOO_P2_KEY)).isEqualTo(1);
-// assertThat(db.qualityProfileDao().selectByUuid(dbSession, XOO_P2_KEY).getParentKee()).isNull();
-// verifyHasActiveRuleInDbAndIndex(ActiveRuleKey.of(XOO_P2_KEY, XOO_X2), MAJOR, null, Collections.emptyMap());
-// }
-//
-// @Test
-// public void unset_no_parent_does_not_fail() {
-// // P1 has no parent !
-// ruleActivator.setParent(dbSession, selectProfile(XOO_P1_KEY), null);
-// assertThat(selectProfile(XOO_P1_KEY).getParentKee()).isNull();
-// }
-//
-// @Test
-// public void fail_if_set_child_as_parent() {
-// createChildProfiles();
-//
-// try {
-// ruleActivator.setParent(dbSession, selectProfile(XOO_P1_KEY), selectProfile(XOO_P3_KEY));
-// fail();
-// } catch (BadRequestException e) {
-// assertThat(e).hasMessage("Descendant profile 'XOO_P3' can not be selected as parent of 'XOO_P1'");
-// }
-// }
-//
-// @Test
-// public void keep_overridden_rules_when_unsetting_parent() {
-// // x1 is activated on the "future parent"
-// RuleActivation activation = new RuleActivation(XOO_X1);
-// activation.setSeverity("MAJOR");
-// activate(activation, XOO_P1_KEY);
-// verifyOneActiveRuleInDb(XOO_P1_KEY, XOO_X1, MAJOR, null, ImmutableMap.of("max", "10"));
-//
-// // create empty profile P2
-// db.qualityProfileDao().insert(dbSession, QProfileTesting.newXooP2("org-123"));
-// dbSession.commit();
-// dbSession.clearCache();
-//
-// // set parent -> child profile inherits rule x1
-// ruleActivator.setParent(dbSession, selectProfile(XOO_P2_KEY), selectProfile(XOO_P1_KEY));
-// verifyOneActiveRuleInDbAndIndex(XOO_P2_KEY, XOO_X1, MAJOR, INHERITED, ImmutableMap.of("max", "10"));
-//
-// // override x1
-// activation = new RuleActivation(XOO_X1);
-// activation.setSeverity("BLOCKER").setParameter("max", "333");
-// activate(activation, XOO_P2_KEY);
-// verifyOneActiveRuleInDb(XOO_P2_KEY, XOO_X1, BLOCKER, OVERRIDES, ImmutableMap.of("max", "333"));
-//
-// // unset parent -> keep x1
-// ruleActivator.setParent(dbSession, selectProfile(XOO_P2_KEY), null);
-// dbSession.clearCache();
-// assertThat(db.qualityProfileDao().selectByUuid(dbSession, XOO_P2_KEY).getParentKee()).isNull();
-// verifyOneActiveRuleInDbAndIndex(XOO_P2_KEY, XOO_X1, BLOCKER, null, ImmutableMap.of("max", "333"));
-// }
//
// @Test
// public void ignore_activation_errors_when_setting_parent() {
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RuleActivatorTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RuleActivatorTest.java
new file mode 100644
index 00000000000..021f0b53a06
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RuleActivatorTest.java
@@ -0,0 +1,967 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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 java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import javax.annotation.Nullable;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.PropertyType;
+import org.sonar.api.config.MapSettings;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rule.RuleStatus;
+import org.sonar.api.rule.Severity;
+import org.sonar.api.utils.System2;
+import org.sonar.api.utils.internal.AlwaysIncreasingSystem2;
+import org.sonar.db.DbTester;
+import org.sonar.db.qualityprofile.ActiveRuleParamDto;
+import org.sonar.db.qualityprofile.OrgActiveRuleDto;
+import org.sonar.db.qualityprofile.QProfileDto;
+import org.sonar.db.rule.RuleDefinitionDto;
+import org.sonar.db.rule.RuleParamDto;
+import org.sonar.server.es.EsTester;
+import org.sonar.server.exceptions.BadRequestException;
+import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
+import org.sonar.server.qualityprofile.index.ActiveRuleIteratorFactory;
+import org.sonar.server.rule.index.RuleIndex;
+import org.sonar.server.rule.index.RuleIndexDefinition;
+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 com.google.common.collect.ImmutableMap.of;
+import static java.util.Arrays.asList;
+import static java.util.Collections.emptyMap;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.fail;
+import static org.sonar.api.rule.Severity.BLOCKER;
+import static org.sonar.api.rule.Severity.CRITICAL;
+import static org.sonar.api.rule.Severity.MAJOR;
+
+public class RuleActivatorTest {
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ private System2 system2 = new AlwaysIncreasingSystem2();
+ @Rule
+ public DbTester db = DbTester.create(system2);
+ @Rule
+ public EsTester es = new EsTester(RuleIndexDefinition.createForTest(new MapSettings()));
+ @Rule
+ public UserSessionRule userSession = UserSessionRule.standalone();
+ private RuleIndex ruleIndex = new RuleIndex(es.client());
+ private RuleActivatorContextFactory contextFactory = new RuleActivatorContextFactory(db.getDbClient());
+ private ActiveRuleIteratorFactory activeRuleIteratorFactory = new ActiveRuleIteratorFactory(db.getDbClient());
+ private ActiveRuleIndexer activeRuleIndexer = new ActiveRuleIndexer(db.getDbClient(), es.client(), activeRuleIteratorFactory);
+ private TypeValidations typeValidations = new TypeValidations(asList(new StringTypeValidation(), new IntegerTypeValidation()));
+
+ private RuleActivator underTest = new RuleActivator(system2, db.getDbClient(), ruleIndex, contextFactory, typeValidations, activeRuleIndexer,
+ userSession);
+
+ @Test
+ public void system_activates_rule_without_parameters() {
+ RuleDefinitionDto rule = createRule();
+ QProfileDto profile = createProfile(rule);
+ RuleActivation activation = new RuleActivation(rule.getKey());
+ activation.setSeverity(BLOCKER);
+ List<ActiveRuleChange> changes = activate(profile, activation);
+
+ assertThatRuleIsActivated(profile, rule, changes, BLOCKER, null, emptyMap());
+ assertThatProfileIsUpdatedBySystem(profile);
+ }
+
+ @Test
+ public void user_activates_rule_without_parameters() {
+ userSession.logIn();
+ RuleDefinitionDto rule = createRule();
+ QProfileDto profile = createProfile(rule);
+ RuleActivation activation = new RuleActivation(rule.getKey());
+ activation.setSeverity(BLOCKER);
+ List<ActiveRuleChange> changes = activate(profile, activation);
+
+ assertThatRuleIsActivated(profile, rule, changes, BLOCKER, null, emptyMap());
+ assertThatProfileIsUpdatedByUser(profile);
+ }
+
+ @Test
+ public void activate_rule_with_default_severity_and_parameters() {
+ RuleDefinitionDto rule = createRule();
+ RuleParamDto ruleParam = db.rules().insertRuleParam(rule, p -> p.setName("min").setDefaultValue("10"));
+ QProfileDto profile = createProfile(rule);
+
+ RuleActivation activation = new RuleActivation(rule.getKey());
+ List<ActiveRuleChange> changes = activate(profile, activation);
+
+ assertThatRuleIsActivated(profile, rule, changes, rule.getSeverityString(), null, of("min", "10"));
+ assertThatProfileIsUpdatedBySystem(profile);
+ }
+
+ @Test
+ public void activate_rule_with_parameters() {
+ RuleDefinitionDto rule = createRule();
+ RuleParamDto ruleParam = db.rules().insertRuleParam(rule, p -> p.setName("min").setDefaultValue("10"));
+ QProfileDto profile = createProfile(rule);
+
+ RuleActivation activation = new RuleActivation(rule.getKey())
+ .setParameter(ruleParam.getName(), "15");
+ List<ActiveRuleChange> changes = activate(profile, activation);
+
+ assertThatRuleIsActivated(profile, rule, changes, rule.getSeverityString(), null, of("min", "15"));
+ assertThatProfileIsUpdatedBySystem(profile);
+ }
+
+ @Test
+ public void activate_rule_with_default_severity() {
+ RuleDefinitionDto rule = createRule();
+ QProfileDto profile = createProfile(rule);
+
+ RuleActivation activation = new RuleActivation(rule.getKey());
+ List<ActiveRuleChange> changes = activate(profile, activation);
+
+ assertThatRuleIsActivated(profile, rule, changes, rule.getSeverityString(), null, emptyMap());
+ assertThatProfileIsUpdatedBySystem(profile);
+ }
+
+ /**
+ * SONAR-5841
+ */
+ @Test
+ public void activate_rule_with_empty_parameter_having_no_default_value() {
+ RuleDefinitionDto rule = createRule();
+ RuleParamDto ruleParam = db.rules().insertRuleParam(rule, p -> p.setName("min").setDefaultValue("10"));
+ QProfileDto profile = createProfile(rule);
+
+ RuleActivation activation = new RuleActivation(rule.getKey())
+ .setParameter("min", "");
+ List<ActiveRuleChange> changes = activate(profile, activation);
+
+ assertThatRuleIsActivated(profile, rule, changes, rule.getSeverityString(), null, of("min", "10"));
+ assertThatProfileIsUpdatedBySystem(profile);
+ }
+
+ /**
+ // * SONAR-5840
+ // */
+ @Test
+ public void activate_rule_with_negative_integer_value_on_parameter_having_no_default_value() {
+ RuleDefinitionDto rule = createRule();
+ RuleParamDto paramWithoutDefault = db.rules().insertRuleParam(rule, p -> p.setName("min").setDefaultValue(null));
+ RuleParamDto paramWithDefault = db.rules().insertRuleParam(rule, p -> p.setName("max").setDefaultValue("10"));
+ QProfileDto profile = createProfile(rule);
+
+ RuleActivation activation = new RuleActivation(rule.getKey())
+ .setParameter(paramWithoutDefault.getName(), "-10");
+ List<ActiveRuleChange> changes = activate(profile, activation);
+
+ assertThatRuleIsActivated(profile, rule, changes, rule.getSeverityString(), null,
+ of(paramWithoutDefault.getName(), "-10", paramWithDefault.getName(), paramWithDefault.getDefaultValue()));
+ assertThatProfileIsUpdatedBySystem(profile);
+ }
+
+ @Test
+ public void activation_ignores_unsupported_parameters() {
+ RuleDefinitionDto rule = createRule();
+ RuleParamDto param = db.rules().insertRuleParam(rule, p -> p.setName("max").setDefaultValue("10"));
+ QProfileDto profile = createProfile(rule);
+
+ RuleActivation activation = new RuleActivation(rule.getKey())
+ .setParameter("xxx", "yyy");
+ List<ActiveRuleChange> changes = activate(profile, activation);
+
+ assertThatRuleIsActivated(profile, rule, changes, rule.getSeverityString(), null, of(param.getName(), param.getDefaultValue()));
+ assertThatProfileIsUpdatedBySystem(profile);
+ }
+
+ @Test
+ public void update_an_already_activated_rule() {
+ RuleDefinitionDto rule = createRule();
+ RuleParamDto param = db.rules().insertRuleParam(rule, p -> p.setName("max").setDefaultValue("10"));
+ QProfileDto profile = createProfile(rule);
+
+ // initial activation
+ RuleActivation activation = new RuleActivation(rule.getKey())
+ .setSeverity(MAJOR);
+ activate(profile, activation);
+
+ // update
+ RuleActivation updateActivation = new RuleActivation(rule.getKey())
+ .setSeverity(CRITICAL)
+ .setParameter(param.getName(), "20");
+ List<ActiveRuleChange> changes = activate(profile, updateActivation);
+
+ assertThatRuleIsUpdated(profile, rule, CRITICAL, null, of(param.getName(), "20"));
+ assertThatProfileIsUpdatedBySystem(profile);
+ }
+
+ @Test
+ public void update_activation_with_parameter_without_default_value() {
+ RuleDefinitionDto rule = createRule();
+ RuleParamDto paramWithoutDefault = db.rules().insertRuleParam(rule, p -> p.setName("min").setDefaultValue(null));
+ RuleParamDto paramWithDefault = db.rules().insertRuleParam(rule, p -> p.setName("max").setDefaultValue("10"));
+ QProfileDto profile = createProfile(rule);
+
+ // initial activation -> param "max" has a default value
+ RuleActivation activation = new RuleActivation(rule.getKey());
+ activate(profile, activation);
+
+ // update param "min", which has no default value
+ RuleActivation updateActivation = new RuleActivation(rule.getKey())
+ .setSeverity(MAJOR)
+ .setParameter(paramWithoutDefault.getName(), "3");
+ List<ActiveRuleChange> changes = activate(profile, updateActivation);
+
+ assertThatRuleIsUpdated(profile, rule, MAJOR, null, of(paramWithDefault.getName(), "10", paramWithoutDefault.getName(), "3"));
+ assertThatProfileIsUpdatedBySystem(profile);
+ }
+
+ @Test
+ public void reset_parameter_to_default_value() {
+ RuleDefinitionDto rule = createRule();
+ RuleParamDto paramWithDefault = db.rules().insertRuleParam(rule, p -> p.setName("max").setDefaultValue("10"));
+ QProfileDto profile = createProfile(rule);
+
+ // initial activation -> param "max" has a default value
+ RuleActivation activation = new RuleActivation(rule.getKey())
+ .setParameter(paramWithDefault.getName(), "20");
+ activate(profile, activation);
+
+ // reset to default_value
+ RuleActivation updateActivation = new RuleActivation(rule.getKey())
+ .setParameter(paramWithDefault.getName(), null);
+ List<ActiveRuleChange> changes = activate(profile, updateActivation);
+
+ assertThatRuleIsUpdated(profile, rule, rule.getSeverityString(), null, of(paramWithDefault.getName(), "10"));
+ assertThat(changes).hasSize(1);
+ }
+
+ @Test
+ public void update_activation_removes_parameter_without_default_value() {
+ RuleDefinitionDto rule = createRule();
+ RuleParamDto paramWithoutDefault = db.rules().insertRuleParam(rule, p -> p.setName("min").setDefaultValue(null));
+ RuleParamDto paramWithDefault = db.rules().insertRuleParam(rule, p -> p.setName("max").setDefaultValue("10"));
+ QProfileDto profile = createProfile(rule);
+
+ // initial activation -> param "max" has a default value
+ RuleActivation activation = new RuleActivation(rule.getKey())
+ .setParameter(paramWithoutDefault.getName(), "20");
+ activate(profile, activation);
+
+ // remove parameter
+ RuleActivation updateActivation = new RuleActivation(rule.getKey())
+ .setParameter(paramWithoutDefault.getName(), null);
+ List<ActiveRuleChange> changes = activate(profile, updateActivation);
+
+ assertThatRuleIsUpdated(profile, rule, rule.getSeverityString(), null, of(paramWithDefault.getName(), paramWithDefault.getDefaultValue()));
+ assertThat(changes).hasSize(1);
+ }
+
+ @Test
+ public void update_activation_with_new_parameter() {
+ RuleDefinitionDto rule = createRule();
+ RuleParamDto param = db.rules().insertRuleParam(rule, p -> p.setName("max").setDefaultValue("10"));
+ QProfileDto profile = createProfile(rule);
+
+ // initial activation -> param "max" has a default value
+ RuleActivation activation = new RuleActivation(rule.getKey());
+ List<ActiveRuleChange> changes = activate(profile, activation);
+ db.getDbClient().activeRuleDao().deleteParametersByRuleProfileUuids(db.getSession(), asList(profile.getRulesProfileUuid()));
+ assertThatRuleIsActivated(profile, rule, changes, rule.getSeverityString(), null, emptyMap());
+
+ // contrary to activerule, the param is supposed to be inserted but not updated
+ RuleActivation updateActivation = new RuleActivation(rule.getKey())
+ .setParameter(param.getName(), null);
+ changes = activate(profile, updateActivation);
+
+ assertThatRuleIsUpdated(profile, rule, rule.getSeverityString(), null, of(param.getName(), param.getDefaultValue()));
+ assertThat(changes).hasSize(1);
+ }
+
+ @Test
+ public void ignore_activation_without_changes() {
+ RuleDefinitionDto rule = createRule();
+ QProfileDto profile = createProfile(rule);
+
+ // initial activation
+ RuleActivation activation = new RuleActivation(rule.getKey());
+ activate(profile, activation);
+
+ // update with exactly the same severity and params
+ activation = new RuleActivation(rule.getKey());
+ List<ActiveRuleChange> changes = activate(profile, activation);
+
+ assertThat(changes).isEmpty();
+ }
+
+ @Test
+ public void do_not_change_severity_and_params_if_unset_and_already_activated() {
+ RuleDefinitionDto rule = createRule();
+ RuleParamDto param = db.rules().insertRuleParam(rule, p -> p.setName("max").setDefaultValue("10"));
+ QProfileDto profile = createProfile(rule);
+
+ // initial activation -> param "max" has a default value
+ RuleActivation activation = new RuleActivation(rule.getKey())
+ .setSeverity(BLOCKER)
+ .setParameter(param.getName(), "20");
+ activate(profile, activation);
+
+ // update without any severity or params => keep
+ RuleActivation update = new RuleActivation(rule.getKey());
+ List<ActiveRuleChange> changes = activate(profile, update);
+
+ assertThat(changes).isEmpty();
+ }
+
+ @Test
+ public void activation_fails_if_rule_does_not_exist() {
+ RuleDefinitionDto rule = createRule();
+ QProfileDto profile = createProfile(rule);
+ RuleKey ruleKey = RuleKey.parse("unknown:xxx");
+ RuleActivation activation = new RuleActivation(ruleKey);
+
+ expectFailure("Rule not found: " + ruleKey, () -> activate(profile, activation));
+ }
+
+ @Test
+ public void fail_to_activate_rule_if_profile_is_on_different_languages() {
+ RuleDefinitionDto rule = createJavaRule();
+ QProfileDto profile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage("js"));
+ RuleActivation activation = new RuleActivation(rule.getKey());
+
+ expectFailure("Rule " + rule.getKey() + " and profile " + profile.getKee() + " have different languages", () -> activate(profile, activation));
+ }
+
+ @Test
+ public void fail_to_activate_rule_if_rule_has_REMOVED_status() {
+ RuleDefinitionDto rule = db.rules().insert(r -> r.setStatus(RuleStatus.REMOVED));
+ QProfileDto profile = createProfile(rule);
+ RuleActivation activation = new RuleActivation(rule.getKey());
+
+ expectFailure("Rule was removed: " + rule.getKey(), () -> activate(profile, activation));
+ }
+
+ @Test
+ public void fail_to_activate_if_template() {
+ RuleDefinitionDto rule = db.rules().insert(r -> r.setIsTemplate(true));
+ QProfileDto profile = createProfile(rule);
+ RuleActivation activation = new RuleActivation(rule.getKey());
+
+ expectFailure("Rule template can't be activated on a Quality profile: " + rule.getKey(), () -> activate(profile, activation));
+ }
+
+ @Test
+ public void fail_to_activate_if_invalid_parameter() {
+ RuleDefinitionDto rule = createRule();
+ RuleParamDto param = db.rules().insertRuleParam(rule, p -> p.setName("max").setDefaultValue("10").setType(PropertyType.INTEGER.name()));
+ QProfileDto profile = createProfile(rule);
+
+ RuleActivation activation = new RuleActivation(rule.getKey())
+ .setParameter(param.getName(), "foo");
+ expectFailure("Value 'foo' must be an integer.", () -> activate(profile, activation));
+ }
+
+ @Test
+ public void user_deactivates_a_rule() {
+ userSession.logIn();
+ RuleDefinitionDto rule = createRule();
+ QProfileDto profile = createProfile(rule);
+ RuleActivation activation = new RuleActivation(rule.getKey());
+ activate(profile, activation);
+
+ List<ActiveRuleChange> changes = deactivate(profile, rule);
+ verifyNoActiveRules();
+ assertThatProfileIsUpdatedByUser(profile);
+ assertThat(changes).hasSize(1);
+ assertThat(changes.get(0).getType()).isEqualTo(ActiveRuleChange.Type.DEACTIVATED);
+ }
+
+ @Test
+ public void system_deactivates_a_rule() {
+ RuleDefinitionDto rule = createRule();
+ QProfileDto profile = createProfile(rule);
+ RuleActivation activation = new RuleActivation(rule.getKey());
+ activate(profile, activation);
+
+ List<ActiveRuleChange> changes = deactivate(profile, rule);
+ verifyNoActiveRules();
+ assertThatProfileIsUpdatedBySystem(profile);
+ assertThatChangeIsDeactivation(changes, rule);
+ }
+
+ private void assertThatChangeIsDeactivation(List<ActiveRuleChange> changes, RuleDefinitionDto rule) {
+ assertThat(changes).hasSize(1);
+ ActiveRuleChange change = changes.get(0);
+ assertThat(change.getType()).isEqualTo(ActiveRuleChange.Type.DEACTIVATED);
+ assertThat(change.getKey().getRuleKey()).isEqualTo(rule.getKey());
+ }
+
+ @Test
+ public void ignore_deactivation_if_rule_is_not_activated() {
+ RuleDefinitionDto rule = createRule();
+ QProfileDto profile = createProfile(rule);
+
+ List<ActiveRuleChange> changes = deactivate(profile, rule);
+ verifyNoActiveRules();
+ assertThat(changes).hasSize(0);
+ }
+
+ @Test
+ public void deactivation_fails_if_rule_does_not_exist() {
+ RuleDefinitionDto rule = createRule();
+ QProfileDto profile = createProfile(rule);
+ RuleKey ruleKey = RuleKey.parse("unknown:xxx");
+
+ expectFailure("Rule not found: " + ruleKey, () -> underTest.deactivate(db.getSession(), profile, ruleKey));
+ }
+
+ @Test
+ public void deactivate_rule_that_has_REMOVED_status() {
+ RuleDefinitionDto rule = createRule();
+ QProfileDto profile = createProfile(rule);
+ RuleActivation activation = new RuleActivation(rule.getKey());
+ activate(profile, activation);
+
+ rule.setStatus(RuleStatus.REMOVED);
+ db.getDbClient().ruleDao().update(db.getSession(), rule);
+
+ List<ActiveRuleChange> changes = deactivate(profile, rule);
+ verifyNoActiveRules();
+ assertThatChangeIsDeactivation(changes, rule);
+ }
+
+ @Test
+ public void activation_on_child_profile_is_propagated_to_descendants() {
+ RuleDefinitionDto rule = createRule();
+ QProfileDto parentProfile = createProfile(rule);
+ QProfileDto childProfile = createChildProfile(parentProfile);
+ QProfileDto grandChildProfile = createChildProfile(childProfile);
+
+ List<ActiveRuleChange> changes = activate(childProfile, new RuleActivation(rule.getKey()));
+ assertThatProfileHasNoActiveRules(parentProfile);
+ assertThatRuleIsActivated(childProfile, rule, changes, rule.getSeverityString(), null, emptyMap());
+ assertThatRuleIsActivated(grandChildProfile, rule, changes, rule.getSeverityString(), ActiveRule.Inheritance.INHERITED, emptyMap());
+ }
+
+ @Test
+ public void update_on_child_profile_is_propagated_to_descendants() {
+ RuleDefinitionDto rule = createRule();
+ RuleParamDto param = db.rules().insertRuleParam(rule);
+ QProfileDto parentProfile = createProfile(rule);
+ QProfileDto childProfile = createChildProfile(parentProfile);
+ QProfileDto grandChildProfile = createChildProfile(childProfile);
+
+ RuleActivation initialActivation = new RuleActivation(rule.getKey())
+ .setSeverity(MAJOR)
+ .setParameter(param.getName(), "foo");
+ activate(childProfile, initialActivation);
+
+ RuleActivation updateActivation = new RuleActivation(rule.getKey())
+ .setSeverity(CRITICAL)
+ .setParameter(param.getName(), "bar");
+ List<ActiveRuleChange> changes = activate(childProfile, updateActivation);
+
+ assertThatProfileHasNoActiveRules(parentProfile);
+ assertThatRuleIsUpdated(childProfile, rule, CRITICAL, null, of(param.getName(), "bar"));
+ assertThatRuleIsUpdated(grandChildProfile, rule, CRITICAL, ActiveRule.Inheritance.INHERITED, of(param.getName(), "bar"));
+ assertThat(changes).hasSize(2);
+ }
+
+ @Test
+ public void override_activation_of_inherited_profile() {
+ RuleDefinitionDto rule = createRule();
+ RuleParamDto param = db.rules().insertRuleParam(rule);
+ QProfileDto parentProfile = createProfile(rule);
+ QProfileDto childProfile = createChildProfile(parentProfile);
+ QProfileDto grandChildProfile = createChildProfile(childProfile);
+
+ RuleActivation initialActivation = new RuleActivation(rule.getKey())
+ .setSeverity(MAJOR)
+ .setParameter(param.getName(), "foo");
+ activate(childProfile, initialActivation);
+
+ RuleActivation overrideActivation = new RuleActivation(rule.getKey())
+ .setSeverity(CRITICAL)
+ .setParameter(param.getName(), "bar");
+ List<ActiveRuleChange> changes = activate(grandChildProfile, overrideActivation);
+
+ assertThatProfileHasNoActiveRules(parentProfile);
+ assertThatRuleIsUpdated(childProfile, rule, MAJOR, null, of(param.getName(), "foo"));
+ assertThatRuleIsUpdated(grandChildProfile, rule, CRITICAL, ActiveRule.Inheritance.OVERRIDES, of(param.getName(), "bar"));
+ assertThat(changes).hasSize(1);
+ }
+
+ @Test
+ public void updated_activation_on_parent_is_not_propagated_to_overridden_profiles() {
+ RuleDefinitionDto rule = createRule();
+ RuleParamDto param = db.rules().insertRuleParam(rule);
+ QProfileDto parentProfile = createProfile(rule);
+ QProfileDto childProfile = createChildProfile(parentProfile);
+ QProfileDto grandChildProfile = createChildProfile(childProfile);
+
+ RuleActivation initialActivation = new RuleActivation(rule.getKey())
+ .setSeverity(MAJOR)
+ .setParameter(param.getName(), "foo");
+ activate(childProfile, initialActivation);
+
+ RuleActivation overrideActivation = new RuleActivation(rule.getKey())
+ .setSeverity(CRITICAL)
+ .setParameter(param.getName(), "bar");
+ activate(grandChildProfile, overrideActivation);
+
+ // update child --> do not touch grandChild
+ RuleActivation updateActivation = new RuleActivation(rule.getKey())
+ .setSeverity(BLOCKER)
+ .setParameter(param.getName(), "baz");
+ List<ActiveRuleChange> changes = activate(childProfile, updateActivation);
+
+ assertThatProfileHasNoActiveRules(parentProfile);
+ assertThatRuleIsUpdated(childProfile, rule, BLOCKER, null, of(param.getName(), "baz"));
+ assertThatRuleIsUpdated(grandChildProfile, rule, CRITICAL, ActiveRule.Inheritance.OVERRIDES, of(param.getName(), "bar"));
+ assertThat(changes).hasSize(1);
+ }
+
+ @Test
+ public void reset_on_parent_is_not_propagated_to_overridden_profiles() {
+ RuleDefinitionDto rule = createRule();
+ RuleParamDto param = db.rules().insertRuleParam(rule);
+ QProfileDto parentProfile = createProfile(rule);
+ QProfileDto childProfile = createChildProfile(parentProfile);
+ QProfileDto grandChildProfile = createChildProfile(childProfile);
+
+ RuleActivation initialActivation = new RuleActivation(rule.getKey())
+ .setSeverity(MAJOR)
+ .setParameter(param.getName(), "foo");
+ activate(parentProfile, initialActivation);
+
+ RuleActivation overrideActivation = new RuleActivation(rule.getKey())
+ .setSeverity(CRITICAL)
+ .setParameter(param.getName(), "bar");
+ activate(grandChildProfile, overrideActivation);
+
+ // reset parent --> touch child but not grandChild
+ RuleActivation updateActivation = new RuleActivation(rule.getKey())
+ .setReset(true);
+ List<ActiveRuleChange> changes = activate(parentProfile, updateActivation);
+
+ assertThatRuleIsUpdated(parentProfile, rule, rule.getSeverityString(), null, of(param.getName(), param.getDefaultValue()));
+ assertThatRuleIsUpdated(childProfile, rule, rule.getSeverityString(), ActiveRule.Inheritance.INHERITED, of(param.getName(), param.getDefaultValue()));
+ assertThatRuleIsUpdated(grandChildProfile, rule, CRITICAL, ActiveRule.Inheritance.OVERRIDES, of(param.getName(), "bar"));
+ assertThat(changes).hasSize(2);
+ }
+
+ @Test
+ public void active_on_parent_a_rule_already_activated_on_child() {
+ RuleDefinitionDto rule = createRule();
+ RuleParamDto param = db.rules().insertRuleParam(rule);
+ QProfileDto parentProfile = createProfile(rule);
+ QProfileDto childProfile = createChildProfile(parentProfile);
+
+ RuleActivation childActivation = new RuleActivation(rule.getKey())
+ .setSeverity(MAJOR)
+ .setParameter(param.getName(), "foo");
+ activate(childProfile, childActivation);
+
+ RuleActivation parentActivation = new RuleActivation(rule.getKey())
+ .setSeverity(CRITICAL)
+ .setParameter(param.getName(), "bar");
+ List<ActiveRuleChange> changes = activate(parentProfile, parentActivation);
+
+ assertThatRuleIsUpdated(parentProfile, rule, CRITICAL, null, of(param.getName(), "bar"));
+ assertThatRuleIsUpdated(childProfile, rule, MAJOR, ActiveRule.Inheritance.OVERRIDES, of(param.getName(), "foo"));
+ assertThat(changes).hasSize(2);
+ }
+
+ @Test
+ public void do_not_mark_as_overridden_if_same_values_than_parent() {
+ RuleDefinitionDto rule = createRule();
+ RuleParamDto param = db.rules().insertRuleParam(rule);
+ QProfileDto parentProfile = createProfile(rule);
+ QProfileDto childProfile = createChildProfile(parentProfile);
+
+ RuleActivation parentActivation = new RuleActivation(rule.getKey())
+ .setSeverity(MAJOR)
+ .setParameter(param.getName(), "foo");
+ activate(parentProfile, parentActivation);
+
+ RuleActivation overrideActivation = new RuleActivation(rule.getKey())
+ .setSeverity(MAJOR)
+ .setParameter(param.getName(), "foo");
+ List<ActiveRuleChange> changes = activate(childProfile, overrideActivation);
+
+ assertThatRuleIsUpdated(childProfile, rule, MAJOR, ActiveRule.Inheritance.INHERITED, of(param.getName(), "foo"));
+ assertThat(changes).hasSize(0);
+ }
+
+ @Test
+ public void propagate_deactivation_on_children() {
+ RuleDefinitionDto rule = createRule();
+ QProfileDto parentProfile = createProfile(rule);
+ QProfileDto childProfile = createChildProfile(parentProfile);
+
+ RuleActivation activation = new RuleActivation(rule.getKey());
+ List<ActiveRuleChange> changes = activate(parentProfile, activation);
+ assertThatRuleIsActivated(parentProfile, rule, changes, rule.getSeverityString(), null, emptyMap());
+ assertThatRuleIsActivated(childProfile, rule, changes, rule.getSeverityString(), ActiveRule.Inheritance.INHERITED, emptyMap());
+
+ changes = deactivate(parentProfile, rule);
+ assertThatProfileHasNoActiveRules(parentProfile);
+ assertThatProfileHasNoActiveRules(childProfile);
+ assertThat(changes).hasSize(2);
+ }
+
+ @Test
+ public void propagate_deactivation_on_children_even_when_overridden() {
+ RuleDefinitionDto rule = createRule();
+ QProfileDto parentProfile = createProfile(rule);
+ QProfileDto childProfile = createChildProfile(parentProfile);
+
+ RuleActivation activation = new RuleActivation(rule.getKey());
+ List<ActiveRuleChange> changes = activate(parentProfile, activation);
+ assertThatRuleIsActivated(parentProfile, rule, changes, rule.getSeverityString(), null, emptyMap());
+ assertThatRuleIsActivated(childProfile, rule, changes, rule.getSeverityString(), ActiveRule.Inheritance.INHERITED, emptyMap());
+
+ activation = new RuleActivation(rule.getKey())
+ .setSeverity(CRITICAL);
+ activate(childProfile, activation);
+
+ changes = deactivate(parentProfile, rule);
+ assertThatProfileHasNoActiveRules(parentProfile);
+ assertThatProfileHasNoActiveRules(childProfile);
+ assertThat(changes).hasSize(2);
+ }
+
+ @Test
+ public void cannot_deactivate_rule_inherited() {
+ RuleDefinitionDto rule = createRule();
+ QProfileDto parentProfile = createProfile(rule);
+ QProfileDto childProfile = createChildProfile(parentProfile);
+
+ RuleActivation activation = new RuleActivation(rule.getKey());
+ List<ActiveRuleChange> changes = activate(parentProfile, activation);
+ assertThatRuleIsActivated(parentProfile, rule, changes, rule.getSeverityString(), null, emptyMap());
+ assertThatRuleIsActivated(childProfile, rule, changes, rule.getSeverityString(), ActiveRule.Inheritance.INHERITED, emptyMap());
+
+ expectedException.expect(BadRequestException.class);
+ expectedException.expectMessage("Cannot deactivate inherited rule");
+ deactivate(childProfile, rule);
+ }
+
+ @Test
+ public void reset_child_profile_do_not_change_parent() {
+ RuleDefinitionDto rule = createRule();
+ QProfileDto parentProfile = createProfile(rule);
+ QProfileDto childProfile = createChildProfile(parentProfile);
+
+ RuleActivation activation = new RuleActivation(rule.getKey())
+ .setSeverity(CRITICAL);
+ List<ActiveRuleChange> changes = activate(parentProfile, activation);
+ assertThatRuleIsActivated(parentProfile, rule, changes, CRITICAL, null, emptyMap());
+ assertThatRuleIsActivated(childProfile, rule, changes, CRITICAL, ActiveRule.Inheritance.INHERITED, emptyMap());
+ assertThat(changes).hasSize(2);
+
+ RuleActivation childActivation = new RuleActivation(rule.getKey())
+ .setSeverity(BLOCKER);
+ changes = activate(childProfile, childActivation);
+ assertThatRuleIsUpdated(childProfile, rule, BLOCKER, ActiveRule.Inheritance.OVERRIDES, emptyMap());
+ assertThat(changes).hasSize(1);
+
+ RuleActivation resetActivation = new RuleActivation(rule.getKey()).setReset(true);
+ changes = activate(childProfile, resetActivation);
+ assertThatRuleIsUpdated(childProfile, rule, CRITICAL, ActiveRule.Inheritance.INHERITED, emptyMap());
+ assertThatRuleIsUpdated(parentProfile, rule, CRITICAL, null, emptyMap());
+ assertThat(changes).hasSize(1);
+ }
+
+ @Test
+ public void reset_parent_is_not_propagated_when_child_overrides() {
+ RuleDefinitionDto rule = createRule();
+ QProfileDto parentProfile = createProfile(rule);
+ QProfileDto childProfile = createChildProfile(parentProfile);
+ QProfileDto grandchildProfile = createChildProfile(childProfile);
+
+ RuleActivation activation = new RuleActivation(rule.getKey())
+ .setSeverity(CRITICAL);
+ List<ActiveRuleChange> changes = activate(parentProfile, activation);
+ assertThatRuleIsActivated(parentProfile, rule, changes, CRITICAL, null, emptyMap());
+ assertThatRuleIsActivated(childProfile, rule, changes, CRITICAL, ActiveRule.Inheritance.INHERITED, emptyMap());
+ assertThatRuleIsActivated(grandchildProfile, rule, changes, CRITICAL, ActiveRule.Inheritance.INHERITED, emptyMap());
+ assertThat(changes).hasSize(3);
+
+ RuleActivation childActivation = new RuleActivation(rule.getKey())
+ .setSeverity(BLOCKER);
+ changes = activate(childProfile, childActivation);
+ assertThatRuleIsUpdated(childProfile, rule, BLOCKER, ActiveRule.Inheritance.OVERRIDES, emptyMap());
+ assertThatRuleIsUpdated(grandchildProfile, rule, BLOCKER, ActiveRule.Inheritance.INHERITED, emptyMap());
+ assertThat(changes).hasSize(2);
+
+ // Reset on parent do not change child nor grandchild
+ RuleActivation resetActivation = new RuleActivation(rule.getKey()).setReset(true);
+ changes = activate(parentProfile, resetActivation);
+ assertThatRuleIsUpdated(parentProfile, rule, rule.getSeverityString(), null, emptyMap());
+ assertThatRuleIsUpdated(childProfile, rule, BLOCKER, ActiveRule.Inheritance.OVERRIDES, emptyMap());
+ assertThatRuleIsUpdated(grandchildProfile, rule, BLOCKER, ActiveRule.Inheritance.INHERITED, emptyMap());
+ assertThat(changes).hasSize(1);
+
+ // Reset on child change grandchild
+ resetActivation = new RuleActivation(rule.getKey()).setReset(true);
+ changes = activate(childProfile, resetActivation);
+ assertThatRuleIsUpdated(parentProfile, rule, rule.getSeverityString(), null, emptyMap());
+ assertThatRuleIsUpdated(childProfile, rule, rule.getSeverityString(), ActiveRule.Inheritance.INHERITED, emptyMap());
+ assertThatRuleIsUpdated(grandchildProfile, rule, rule.getSeverityString(), ActiveRule.Inheritance.INHERITED, emptyMap());
+ assertThat(changes).hasSize(2);
+ }
+
+ @Test
+ public void ignore_reset_if_not_activated() {
+ RuleDefinitionDto rule = createRule();
+ QProfileDto parentProfile = createProfile(rule);
+ QProfileDto childProfile = createChildProfile(parentProfile);
+
+ RuleActivation resetActivation = new RuleActivation(rule.getKey()).setReset(true);
+ List<ActiveRuleChange> changes = activate(parentProfile, resetActivation);
+ verifyNoActiveRules();
+ assertThat(changes).hasSize(0);
+ }
+
+ @Test
+ public void unset_parent_when_no_parent_does_not_fail() {
+ RuleDefinitionDto rule = createRule();
+ QProfileDto profile = createProfile(rule);
+ underTest.setParent(db.getSession(), profile, null);
+ }
+
+ @Test
+ public void set_itself_as_parent_fails() {
+ RuleDefinitionDto rule = createRule();
+ QProfileDto profile = createProfile(rule);
+
+ expectedException.expect(BadRequestException.class);
+ expectedException.expectMessage(" can not be selected as parent of ");
+ underTest.setParent(db.getSession(), profile, profile);
+ }
+
+ @Test
+ public void set_child_as_parent_fails() {
+ RuleDefinitionDto rule = createRule();
+ QProfileDto parentProfile = createProfile(rule);
+ QProfileDto childProfile = createChildProfile(parentProfile);
+
+ expectedException.expect(BadRequestException.class);
+ expectedException.expectMessage(" can not be selected as parent of ");
+ underTest.setParent(db.getSession(), parentProfile, childProfile);
+ }
+
+ @Test
+ public void set_grandchild_as_parent_fails() {
+ RuleDefinitionDto rule = createRule();
+ QProfileDto parentProfile = createProfile(rule);
+ QProfileDto childProfile = createChildProfile(parentProfile);
+ QProfileDto grandchildProfile = createChildProfile(childProfile);
+
+ expectedException.expect(BadRequestException.class);
+ expectedException.expectMessage(" can not be selected as parent of ");
+ underTest.setParent(db.getSession(), parentProfile, grandchildProfile);
+ }
+
+ @Test
+ public void cannot_set_parent_if_language_is_different() {
+ RuleDefinitionDto rule1 = db.rules().insert(r -> r.setLanguage("foo"));
+ RuleDefinitionDto rule2 = db.rules().insert(r -> r.setLanguage("bar"));
+
+ QProfileDto parentProfile = createProfile(rule1);
+ List<ActiveRuleChange> changes = activate(parentProfile, new RuleActivation(rule1.getKey()));
+ assertThat(changes).hasSize(1);
+
+ QProfileDto childProfile = createProfile(rule2);
+ changes = activate(childProfile, new RuleActivation(rule2.getKey()));
+ assertThat(changes).hasSize(1);
+
+ expectedException.expect(BadRequestException.class);
+ expectedException.expectMessage("Cannot set the profile");
+
+ underTest.setParent(db.getSession(), childProfile, parentProfile);
+ }
+
+ @Test
+ public void set_then_unset_parent() {
+ RuleDefinitionDto rule1 = createJavaRule();
+ RuleDefinitionDto rule2 = createJavaRule();
+
+ QProfileDto profile1 = createProfile(rule1);
+ List<ActiveRuleChange> changes = activate(profile1, new RuleActivation(rule1.getKey()));
+ assertThat(changes).hasSize(1);
+
+ QProfileDto profile2 = createProfile(rule2);
+ changes = activate(profile2, new RuleActivation(rule2.getKey()));
+ assertThat(changes).hasSize(1);
+
+ changes = underTest.setParent(db.getSession(), profile2, profile1);
+ assertThat(changes).hasSize(1);
+ assertThatRuleIsActivated(profile2, rule1, changes, rule1.getSeverityString(), ActiveRule.Inheritance.INHERITED, emptyMap());
+ assertThatRuleIsActivated(profile2, rule2, null, rule2.getSeverityString(), null, emptyMap());
+
+ changes = underTest.setParent(db.getSession(), profile2, null);
+ assertThat(changes).hasSize(1);
+ assertThatRuleIsActivated(profile2, rule2, null, rule2.getSeverityString(), null, emptyMap());
+ assertThatRuleIsNotPresent(profile2, rule1);
+ }
+
+ @Test
+ public void set_then_unset_parent_keep_overridden_rules() {
+ RuleDefinitionDto rule1 = createJavaRule();
+ RuleDefinitionDto rule2 = createJavaRule();
+ QProfileDto profile1 = createProfile(rule1);
+ List<ActiveRuleChange> changes = activate(profile1, new RuleActivation(rule1.getKey()));
+ assertThat(changes).hasSize(1);
+
+ QProfileDto profile2 = createProfile(rule2);
+ changes = activate(profile2, new RuleActivation(rule2.getKey()));
+ assertThat(changes).hasSize(1);
+
+ changes = underTest.setParent(db.getSession(), profile2, profile1);
+ assertThat(changes).hasSize(1);
+ assertThatRuleIsActivated(profile2, rule1, changes, rule1.getSeverityString(), ActiveRule.Inheritance.INHERITED, emptyMap());
+ assertThatRuleIsActivated(profile2, rule2, null, rule2.getSeverityString(), null, emptyMap());
+
+ RuleActivation activation = new RuleActivation(rule1.getKey())
+ .setSeverity(BLOCKER);
+ changes = activate(profile2, activation);
+ assertThat(changes).hasSize(1);
+ assertThatRuleIsUpdated(profile2, rule1, BLOCKER, ActiveRule.Inheritance.OVERRIDES, emptyMap());
+ assertThatRuleIsActivated(profile2, rule2, null, rule2.getSeverityString(), null, emptyMap());
+
+ changes = underTest.setParent(db.getSession(), profile2, null);
+ assertThat(changes).hasSize(1);
+ // Not testing changes here since severity is not set in changelog
+ assertThatRuleIsActivated(profile2, rule1, null, BLOCKER, null, emptyMap());
+ assertThatRuleIsActivated(profile2, rule2, null, rule2.getSeverityString(), null, emptyMap());
+ }
+
+ private void assertThatProfileHasNoActiveRules(QProfileDto profile) {
+ List<OrgActiveRuleDto> activeRules = db.getDbClient().activeRuleDao().selectByProfile(db.getSession(), profile);
+ assertThat(activeRules).isEmpty();
+ }
+
+ private List<ActiveRuleChange> deactivate(QProfileDto profile, RuleDefinitionDto rule) {
+ return underTest.deactivate(db.getSession(), profile, rule.getKey());
+ }
+
+ private List<ActiveRuleChange> activate(QProfileDto profile, RuleActivation activation) {
+ return underTest.activate(db.getSession(), activation, profile);
+ }
+
+ private QProfileDto createProfile(RuleDefinitionDto rule) {
+ return db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(rule.getLanguage()));
+ }
+
+ private QProfileDto createChildProfile(QProfileDto parent) {
+ return db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(parent.getLanguage()).setParentKee(parent.getKee()));
+ }
+
+ private void assertThatProfileIsUpdatedByUser(QProfileDto profile) {
+ QProfileDto loaded = db.getDbClient().qualityProfileDao().selectByUuid(db.getSession(), profile.getKee());
+ assertThat(loaded.getUserUpdatedAt()).isNotNull();
+ assertThat(loaded.getRulesUpdatedAt()).isNotEmpty();
+ }
+
+ private void assertThatProfileIsUpdatedBySystem(QProfileDto profile) {
+ QProfileDto loaded = db.getDbClient().qualityProfileDao().selectByUuid(db.getSession(), profile.getKee());
+ assertThat(loaded.getUserUpdatedAt()).isNull();
+ assertThat(loaded.getRulesUpdatedAt()).isNotEmpty();
+ }
+
+ private void assertThatRuleIsActivated(QProfileDto profile, RuleDefinitionDto rule, @Nullable List<ActiveRuleChange> changes,
+ String expectedSeverity, @Nullable ActiveRule.Inheritance expectedInheritance, Map<String, String> expectedParams) {
+ OrgActiveRuleDto activeRule = db.getDbClient().activeRuleDao().selectByProfile(db.getSession(), profile)
+ .stream()
+ .filter(ar -> ar.getRuleKey().equals(rule.getKey()))
+ .findFirst()
+ .orElseThrow(IllegalStateException::new);
+
+ assertThat(activeRule.getSeverityString()).isEqualTo(expectedSeverity);
+ assertThat(activeRule.getInheritance()).isEqualTo(expectedInheritance != null ? expectedInheritance.name() : null);
+ assertThat(activeRule.getCreatedAt()).isNotNull();
+ assertThat(activeRule.getUpdatedAt()).isNotNull();
+
+ List<ActiveRuleParamDto> params = db.getDbClient().activeRuleDao().selectParamsByActiveRuleId(db.getSession(), activeRule.getId());
+ assertThat(params).hasSize(expectedParams.size());
+
+ if (changes != null) {
+ ActiveRuleChange change = changes.stream()
+ .filter(c -> c.getActiveRule().getId().equals(activeRule.getId()))
+ .findFirst().orElseThrow(IllegalStateException::new);
+ assertThat(change.getInheritance()).isEqualTo(expectedInheritance);
+ assertThat(change.getSeverity()).isEqualTo(expectedSeverity);
+ assertThat(change.getType()).isEqualTo(ActiveRuleChange.Type.ACTIVATED);
+ }
+ }
+
+ private void assertThatRuleIsNotPresent(QProfileDto profile, RuleDefinitionDto rule) {
+ Optional<OrgActiveRuleDto> activeRule = db.getDbClient().activeRuleDao().selectByProfile(db.getSession(), profile)
+ .stream()
+ .filter(ar -> ar.getRuleKey().equals(rule.getKey()))
+ .findFirst();
+
+ assertThat(activeRule).isEmpty();
+ }
+
+ private void assertThatRuleIsUpdated(QProfileDto profile, RuleDefinitionDto rule,
+ String expectedSeverity, @Nullable ActiveRule.Inheritance expectedInheritance, Map<String, String> expectedParams) {
+ OrgActiveRuleDto activeRule = db.getDbClient().activeRuleDao().selectByProfile(db.getSession(), profile)
+ .stream()
+ .filter(ar -> ar.getRuleKey().equals(rule.getKey()))
+ .findFirst()
+ .orElseThrow(IllegalStateException::new);
+
+ assertThat(activeRule.getSeverityString()).isEqualTo(expectedSeverity);
+ assertThat(activeRule.getInheritance()).isEqualTo(expectedInheritance != null ? expectedInheritance.name() : null);
+ assertThat(activeRule.getCreatedAt()).isNotNull();
+ assertThat(activeRule.getUpdatedAt()).isNotNull();
+
+ List<ActiveRuleParamDto> params = db.getDbClient().activeRuleDao().selectParamsByActiveRuleId(db.getSession(), activeRule.getId());
+ assertThat(params).hasSize(expectedParams.size());
+ }
+
+ private void expectFailure(String expectedMessage, Runnable runnable) {
+ try {
+ runnable.run();
+ fail();
+ } catch (BadRequestException e) {
+ assertThat(e.getMessage()).isEqualTo(expectedMessage);
+ }
+ verifyNoActiveRules();
+ }
+
+ private void verifyNoActiveRules() {
+ assertThat(db.countRowsOfTable(db.getSession(), "active_rules")).isEqualTo(0);
+ }
+
+ private RuleDefinitionDto createRule() {
+ return db.rules().insert(r -> r.setSeverity(Severity.MAJOR));
+ }
+
+ private RuleDefinitionDto createJavaRule() {
+ return db.rules().insert(r -> r.setSeverity(Severity.MAJOR).setLanguage("java"));
+ }
+}