summaryrefslogtreecommitdiffstats
path: root/sonar-server/src
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@sonarsource.com>2014-06-06 20:09:16 +0200
committerSimon Brandhof <simon.brandhof@sonarsource.com>2014-06-06 20:09:16 +0200
commit37351e9f46baa1bfe2dd701db4d7764b942d60dc (patch)
tree74f73ff09fb708af755fb5877eaa30183f663e4f /sonar-server/src
parent5df41898c6e29d3db47915777d7fb579f158cab2 (diff)
downloadsonarqube-37351e9f46baa1bfe2dd701db4d7764b942d60dc.tar.gz
sonarqube-37351e9f46baa1bfe2dd701db4d7764b942d60dc.zip
SONAR-5007 fix deactivation of removed rules
Diffstat (limited to 'sonar-server/src')
-rw-r--r--sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java148
-rw-r--r--sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileService.java1
-rw-r--r--sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivator.java60
-rw-r--r--sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivatorContext.java (renamed from sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivationContext.java)38
-rw-r--r--sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivatorContextFactory.java (renamed from sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivationContextFactory.java)29
-rw-r--r--sonar-server/src/main/java/org/sonar/server/rule/RegisterRules.java26
-rw-r--r--sonar-server/src/test/java/org/sonar/server/qualityprofile/RuleActivatorMediumTest.java334
-rw-r--r--sonar-server/src/test/java/org/sonar/server/qualityprofile/RuleChangeTest.java102
-rw-r--r--sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesMediumTest.java153
-rw-r--r--sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesTest.java6
10 files changed, 581 insertions, 316 deletions
diff --git a/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java b/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
index 35a2803784f..a9755d354ca 100644
--- a/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
+++ b/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
@@ -52,7 +52,13 @@ import org.sonar.core.measure.db.MeasureFilterDao;
import org.sonar.core.metric.DefaultMetricFinder;
import org.sonar.core.notification.DefaultNotificationManager;
import org.sonar.core.permission.PermissionFacade;
-import org.sonar.core.persistence.*;
+import org.sonar.core.persistence.DaoUtils;
+import org.sonar.core.persistence.DatabaseVersion;
+import org.sonar.core.persistence.DefaultDatabase;
+import org.sonar.core.persistence.MyBatis;
+import org.sonar.core.persistence.PreviewDatabaseFactory;
+import org.sonar.core.persistence.SemaphoreUpdater;
+import org.sonar.core.persistence.SemaphoresImpl;
import org.sonar.core.preview.PreviewCache;
import org.sonar.core.profiling.Profiling;
import org.sonar.core.purge.PurgeProfiler;
@@ -86,11 +92,33 @@ import org.sonar.server.db.DbClient;
import org.sonar.server.db.EmbeddedDatabaseFactory;
import org.sonar.server.db.migrations.DatabaseMigrations;
import org.sonar.server.db.migrations.DatabaseMigrator;
-import org.sonar.server.debt.*;
+import org.sonar.server.debt.DebtCharacteristicsXMLImporter;
+import org.sonar.server.debt.DebtModelBackup;
+import org.sonar.server.debt.DebtModelLookup;
+import org.sonar.server.debt.DebtModelOperations;
+import org.sonar.server.debt.DebtModelPluginRepository;
+import org.sonar.server.debt.DebtModelService;
+import org.sonar.server.debt.DebtModelXMLExporter;
+import org.sonar.server.debt.DebtRulesXMLImporter;
import org.sonar.server.duplication.ws.DuplicationsParser;
import org.sonar.server.duplication.ws.DuplicationsWriter;
import org.sonar.server.duplication.ws.DuplicationsWs;
-import org.sonar.server.issue.*;
+import org.sonar.server.issue.ActionService;
+import org.sonar.server.issue.AssignAction;
+import org.sonar.server.issue.CommentAction;
+import org.sonar.server.issue.DefaultIssueFinder;
+import org.sonar.server.issue.InternalRubyIssueService;
+import org.sonar.server.issue.IssueBulkChangeService;
+import org.sonar.server.issue.IssueChangelogFormatter;
+import org.sonar.server.issue.IssueChangelogService;
+import org.sonar.server.issue.IssueCommentService;
+import org.sonar.server.issue.IssueService;
+import org.sonar.server.issue.IssueStatsFinder;
+import org.sonar.server.issue.PlanAction;
+import org.sonar.server.issue.PublicRubyIssueService;
+import org.sonar.server.issue.ServerIssueStorage;
+import org.sonar.server.issue.SetSeverityAction;
+import org.sonar.server.issue.TransitionAction;
import org.sonar.server.issue.actionplan.ActionPlanService;
import org.sonar.server.issue.actionplan.ActionPlanWs;
import org.sonar.server.issue.filter.IssueFilterService;
@@ -119,22 +147,83 @@ import org.sonar.server.platform.ws.L10nWs;
import org.sonar.server.platform.ws.RestartHandler;
import org.sonar.server.platform.ws.ServerWs;
import org.sonar.server.platform.ws.SystemWs;
-import org.sonar.server.plugins.*;
+import org.sonar.server.plugins.BatchWs;
+import org.sonar.server.plugins.InstalledPluginReferentialFactory;
+import org.sonar.server.plugins.PluginDownloader;
+import org.sonar.server.plugins.ServerExtensionInstaller;
+import org.sonar.server.plugins.ServerPluginJarInstaller;
+import org.sonar.server.plugins.ServerPluginJarsInstaller;
+import org.sonar.server.plugins.ServerPluginRepository;
+import org.sonar.server.plugins.UpdateCenterClient;
+import org.sonar.server.plugins.UpdateCenterMatrixFactory;
import org.sonar.server.qualitygate.QgateProjectFinder;
import org.sonar.server.qualitygate.QualityGates;
import org.sonar.server.qualitygate.RegisterQualityGates;
-import org.sonar.server.qualitygate.ws.*;
-import org.sonar.server.qualityprofile.*;
+import org.sonar.server.qualitygate.ws.QGatesAppAction;
+import org.sonar.server.qualitygate.ws.QGatesCopyAction;
+import org.sonar.server.qualitygate.ws.QGatesCreateAction;
+import org.sonar.server.qualitygate.ws.QGatesCreateConditionAction;
+import org.sonar.server.qualitygate.ws.QGatesDeleteConditionAction;
+import org.sonar.server.qualitygate.ws.QGatesDeselectAction;
+import org.sonar.server.qualitygate.ws.QGatesDestroyAction;
+import org.sonar.server.qualitygate.ws.QGatesListAction;
+import org.sonar.server.qualitygate.ws.QGatesRenameAction;
+import org.sonar.server.qualitygate.ws.QGatesSearchAction;
+import org.sonar.server.qualitygate.ws.QGatesSelectAction;
+import org.sonar.server.qualitygate.ws.QGatesSetAsDefaultAction;
+import org.sonar.server.qualitygate.ws.QGatesShowAction;
+import org.sonar.server.qualitygate.ws.QGatesUnsetDefaultAction;
+import org.sonar.server.qualitygate.ws.QGatesUpdateConditionAction;
+import org.sonar.server.qualitygate.ws.QGatesWs;
+import org.sonar.server.qualityprofile.BuiltInProfiles;
+import org.sonar.server.qualityprofile.ProfilesManager;
+import org.sonar.server.qualityprofile.QProfileBackuper;
+import org.sonar.server.qualityprofile.QProfileCopier;
+import org.sonar.server.qualityprofile.QProfileLookup;
+import org.sonar.server.qualityprofile.QProfileOperations;
+import org.sonar.server.qualityprofile.QProfileProjectLookup;
+import org.sonar.server.qualityprofile.QProfileProjectOperations;
+import org.sonar.server.qualityprofile.QProfileRepositoryExporter;
+import org.sonar.server.qualityprofile.QProfileReset;
+import org.sonar.server.qualityprofile.QProfileService;
+import org.sonar.server.qualityprofile.QProfiles;
+import org.sonar.server.qualityprofile.RegisterQualityProfiles;
+import org.sonar.server.qualityprofile.RuleActivator;
+import org.sonar.server.qualityprofile.RuleActivatorContextFactory;
import org.sonar.server.qualityprofile.db.ActiveRuleDao;
import org.sonar.server.qualityprofile.index.ActiveRuleIndex;
import org.sonar.server.qualityprofile.index.ActiveRuleNormalizer;
-import org.sonar.server.qualityprofile.ws.*;
-import org.sonar.server.rule.*;
+import org.sonar.server.qualityprofile.ws.BulkRuleActivationActions;
+import org.sonar.server.qualityprofile.ws.ProfilesWs;
+import org.sonar.server.qualityprofile.ws.QProfileRecreateBuiltInAction;
+import org.sonar.server.qualityprofile.ws.QProfilesWs;
+import org.sonar.server.qualityprofile.ws.RuleActivationActions;
+import org.sonar.server.rule.DeprecatedRulesDefinition;
+import org.sonar.server.rule.RegisterRules;
+import org.sonar.server.rule.RubyRuleService;
+import org.sonar.server.rule.RuleCreator;
+import org.sonar.server.rule.RuleDefinitionsLoader;
+import org.sonar.server.rule.RuleDeleter;
+import org.sonar.server.rule.RuleOperations;
+import org.sonar.server.rule.RuleRepositories;
+import org.sonar.server.rule.RuleService;
+import org.sonar.server.rule.RuleUpdater;
import org.sonar.server.rule.db.RuleDao;
import org.sonar.server.rule.index.RuleIndex;
import org.sonar.server.rule.index.RuleNormalizer;
-import org.sonar.server.rule.ws.*;
-import org.sonar.server.search.*;
+import org.sonar.server.rule.ws.ActiveRuleCompleter;
+import org.sonar.server.rule.ws.AppAction;
+import org.sonar.server.rule.ws.DeleteAction;
+import org.sonar.server.rule.ws.RuleMapping;
+import org.sonar.server.rule.ws.RulesWebService;
+import org.sonar.server.rule.ws.SearchAction;
+import org.sonar.server.rule.ws.TagsAction;
+import org.sonar.server.rule.ws.UpdateAction;
+import org.sonar.server.search.ESNode;
+import org.sonar.server.search.IndexClient;
+import org.sonar.server.search.IndexQueue;
+import org.sonar.server.search.IndexQueueWorker;
+import org.sonar.server.search.IndexSynchronizer;
import org.sonar.server.source.CodeColorizers;
import org.sonar.server.source.DeprecatedSourceDecorator;
import org.sonar.server.source.HtmlSourceDecorator;
@@ -143,9 +232,27 @@ import org.sonar.server.source.ws.ScmAction;
import org.sonar.server.source.ws.ScmWriter;
import org.sonar.server.source.ws.ShowAction;
import org.sonar.server.source.ws.SourcesWs;
-import org.sonar.server.startup.*;
+import org.sonar.server.startup.CleanPreviewAnalysisCache;
+import org.sonar.server.startup.CopyRequirementsFromCharacteristicsToRules;
+import org.sonar.server.startup.GeneratePluginIndex;
+import org.sonar.server.startup.GwtPublisher;
+import org.sonar.server.startup.JdbcDriverDeployer;
+import org.sonar.server.startup.LogServerId;
+import org.sonar.server.startup.RegisterDashboards;
+import org.sonar.server.startup.RegisterDebtModel;
+import org.sonar.server.startup.RegisterMetrics;
+import org.sonar.server.startup.RegisterNewMeasureFilters;
+import org.sonar.server.startup.RegisterPermissionTemplates;
+import org.sonar.server.startup.RegisterServletFilters;
+import org.sonar.server.startup.RenameDeprecatedPropertyKeys;
+import org.sonar.server.startup.ServerMetadataPersister;
import org.sonar.server.test.CoverageService;
-import org.sonar.server.test.ws.*;
+import org.sonar.server.test.ws.CoverageShowAction;
+import org.sonar.server.test.ws.CoverageWs;
+import org.sonar.server.test.ws.TestsCoveredFilesAction;
+import org.sonar.server.test.ws.TestsShowAction;
+import org.sonar.server.test.ws.TestsTestCasesAction;
+import org.sonar.server.test.ws.TestsWs;
import org.sonar.server.text.MacroInterpreter;
import org.sonar.server.text.RubyTextService;
import org.sonar.server.ui.JRubyI18n;
@@ -153,9 +260,20 @@ import org.sonar.server.ui.JRubyProfiling;
import org.sonar.server.ui.PageDecorations;
import org.sonar.server.ui.Views;
import org.sonar.server.updatecenter.ws.UpdateCenterWs;
-import org.sonar.server.user.*;
+import org.sonar.server.user.DefaultUserService;
+import org.sonar.server.user.DoPrivileged;
+import org.sonar.server.user.GroupMembershipFinder;
+import org.sonar.server.user.GroupMembershipService;
+import org.sonar.server.user.NewUserNotifier;
+import org.sonar.server.user.SecurityRealmFactory;
import org.sonar.server.user.ws.UsersWs;
-import org.sonar.server.util.*;
+import org.sonar.server.util.BooleanTypeValidation;
+import org.sonar.server.util.FloatTypeValidation;
+import org.sonar.server.util.IntegerTypeValidation;
+import org.sonar.server.util.StringListTypeValidation;
+import org.sonar.server.util.StringTypeValidation;
+import org.sonar.server.util.TextTypeValidation;
+import org.sonar.server.util.TypeValidations;
import org.sonar.server.ws.ListingWs;
import org.sonar.server.ws.WebServiceEngine;
@@ -319,7 +437,7 @@ class ServerComponents {
pico.addSingleton(BulkRuleActivationActions.class);
pico.addSingleton(RuleActivator.class);
pico.addSingleton(QProfileService.class);
- pico.addSingleton(RuleActivationContextFactory.class);
+ pico.addSingleton(RuleActivatorContextFactory.class);
pico.addSingleton(QProfileCopier.class);
pico.addSingleton(QProfileBackuper.class);
pico.addSingleton(QProfileReset.class);
diff --git a/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileService.java b/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileService.java
index 20b358c7da2..0d74a2caa81 100644
--- a/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileService.java
+++ b/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileService.java
@@ -106,7 +106,6 @@ public class QProfileService implements ServerComponent {
return ruleActivator.deactivate(key);
}
-
public Multimap<String, String> bulkActivate(RuleQuery ruleQuery, QualityProfileKey profile, @Nullable String severity) {
verifyAdminPermission();
return ruleActivator.bulkActivate(ruleQuery, profile, severity);
diff --git a/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivator.java b/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivator.java
index 394e8fa9fc1..afbebafd5b2 100644
--- a/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivator.java
+++ b/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivator.java
@@ -34,6 +34,7 @@ import org.sonar.core.qualityprofile.db.ActiveRuleKey;
import org.sonar.core.qualityprofile.db.ActiveRuleParamDto;
import org.sonar.core.qualityprofile.db.QualityProfileDto;
import org.sonar.core.qualityprofile.db.QualityProfileKey;
+import org.sonar.core.rule.RuleDto;
import org.sonar.core.rule.RuleParamDto;
import org.sonar.server.db.DbClient;
import org.sonar.server.exceptions.BadRequestException;
@@ -66,13 +67,13 @@ public class RuleActivator implements ServerComponent {
private final DbClient db;
private final TypeValidations typeValidations;
- private final RuleActivationContextFactory contextFactory;
+ private final RuleActivatorContextFactory contextFactory;
private final PreviewCache previewCache;
private final IndexClient index;
private final LogService log;
public RuleActivator(DbClient db, IndexClient index,
- RuleActivationContextFactory contextFactory, TypeValidations typeValidations,
+ RuleActivatorContextFactory contextFactory, TypeValidations typeValidations,
PreviewCache previewCache, LogService log) {
this.db = db;
this.index = index;
@@ -100,7 +101,8 @@ public class RuleActivator implements ServerComponent {
}
List<ActiveRuleChange> activate(DbSession dbSession, RuleActivation activation) {
- RuleActivationContext context = contextFactory.create(activation.getKey(), dbSession);
+ RuleActivatorContext context = contextFactory.create(activation.getKey(), dbSession);
+ context.verifyForActivation();
List<ActiveRuleChange> changes = Lists.newArrayList();
ActiveRuleChange change;
if (context.activeRule() == null) {
@@ -169,7 +171,7 @@ public class RuleActivator implements ServerComponent {
return changes;
}
- private ActiveRuleDto persist(ActiveRuleChange change, RuleActivationContext context, DbSession dbSession) {
+ private ActiveRuleDto persist(ActiveRuleChange change, RuleActivatorContext context, DbSession dbSession) {
ActiveRuleDao dao = db.activeRuleDao();
ActiveRuleDto activeRule = null;
if (change.getType() == ActiveRuleChange.Type.ACTIVATED) {
@@ -244,32 +246,55 @@ public class RuleActivator implements ServerComponent {
* Deactivate a rule on a Quality profile WITHOUT committing db session and WITHOUT checking permissions
*/
List<ActiveRuleChange> deactivate(DbSession dbSession, ActiveRuleKey key) {
- return cascadeDeactivation(key, dbSession, false);
+ return deactivate(dbSession, key, false);
}
- private List<ActiveRuleChange> cascadeDeactivation(ActiveRuleKey key, DbSession dbSession, boolean isCascade) {
+ public List<ActiveRuleChange> deactivate(RuleDto ruleDto) {
+ DbSession dbSession = db.openSession(false);
+ try {
+ return deactivate(dbSession, ruleDto);
+ } finally {
+ dbSession.close();
+ }
+ }
+
+ private List<ActiveRuleChange> deactivate(DbSession dbSession, RuleDto ruleDto) {
+ List<ActiveRuleChange> changes = Lists.newArrayList();
+ List<ActiveRuleDto> activeRules = db.activeRuleDao().findByRule(dbSession, ruleDto);
+ for (ActiveRuleDto activeRule : activeRules) {
+ changes.addAll(deactivate(dbSession, activeRule.getKey(), true));
+ }
+ dbSession.commit();
+ return changes;
+ }
+
+ /**
+ * @param force if true then inherited rules are deactivated
+ */
+ private List<ActiveRuleChange> deactivate(DbSession dbSession, ActiveRuleKey key, boolean force) {
+ return cascadeDeactivation(key, dbSession, false, force);
+ }
+
+ private List<ActiveRuleChange> cascadeDeactivation(ActiveRuleKey key, DbSession dbSession, boolean isCascade, boolean force) {
List<ActiveRuleChange> changes = Lists.newArrayList();
- RuleActivationContext context = contextFactory.create(key, dbSession);
+ RuleActivatorContext context = contextFactory.create(key, dbSession);
ActiveRuleChange change;
if (context.activeRule() == null) {
return changes;
}
- if (!isCascade && (context.activeRule().isInherited() ||
- context.activeRule().doesOverride())) {
+ if (!force && !isCascade && context.activeRule().getInheritance() != null) {
throw new IllegalStateException("Cannot deactivate inherited rule '" + key.ruleKey() + "'");
}
change = new ActiveRuleChange(ActiveRuleChange.Type.DEACTIVATED, key);
changes.add(change);
persist(change, context, dbSession);
-
// get all inherited profiles
- List<QualityProfileDto> profiles =
- db.qualityProfileDao().findByParentKey(dbSession, key.qProfile());
+ List<QualityProfileDto> profiles = db.qualityProfileDao().findByParentKey(dbSession, key.qProfile());
for (QualityProfileDto profile : profiles) {
ActiveRuleKey activeRuleKey = ActiveRuleKey.of(profile.getKey(), key.ruleKey());
- changes.addAll(cascadeDeactivation(activeRuleKey, dbSession, true));
+ changes.addAll(cascadeDeactivation(activeRuleKey, dbSession, true, force));
}
if (!changes.isEmpty()) {
@@ -370,8 +395,8 @@ public class RuleActivator implements ServerComponent {
RuleActivation activation = new RuleActivation(ActiveRuleKey.of(key, parentActiveRule.getKey().ruleKey()));
activate(dbSession, activation);
}
- dbSession.commit();
}
+ dbSession.commit();
} finally {
dbSession.close();
@@ -386,7 +411,12 @@ public class RuleActivator implements ServerComponent {
profileDto.setParent(null);
db.qualityProfileDao().update(dbSession, profileDto);
for (ActiveRuleDto activeRule : db.activeRuleDao().findByProfileKey(dbSession, profileDto.getKey())) {
- deactivate(dbSession, activeRule.getKey());
+ if (ActiveRuleDto.INHERITED.equals(activeRule.getInheritance())) {
+ deactivate(dbSession, activeRule.getKey(), true);
+ } else if (ActiveRuleDto.OVERRIDES.equals(activeRule.getInheritance())) {
+ activeRule.setInheritance(null);
+ db.activeRuleDao().update(dbSession, activeRule);
+ }
}
}
}
diff --git a/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivationContext.java b/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivatorContext.java
index 25ba2e92a45..f4f279fb1b4 100644
--- a/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivationContext.java
+++ b/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivatorContext.java
@@ -21,18 +21,22 @@ package org.sonar.server.qualityprofile;
import com.google.common.collect.Maps;
import org.apache.commons.lang.StringUtils;
+import org.sonar.api.rule.RuleStatus;
+import org.sonar.check.Cardinality;
import org.sonar.core.qualityprofile.db.ActiveRuleDto;
import org.sonar.core.qualityprofile.db.ActiveRuleParamDto;
import org.sonar.core.qualityprofile.db.QualityProfileDto;
import org.sonar.core.rule.RuleDto;
import org.sonar.core.rule.RuleParamDto;
+import org.sonar.server.exceptions.BadRequestException;
+import org.sonar.server.rule.Rule;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.Map;
-class RuleActivationContext {
+class RuleActivatorContext {
private RuleDto rule;
private final Map<String, RuleParamDto> ruleParams = Maps.newHashMap();
@@ -44,7 +48,7 @@ class RuleActivationContext {
return rule;
}
- RuleActivationContext setRule(RuleDto rule) {
+ RuleActivatorContext setRule(RuleDto rule) {
this.rule = rule;
return this;
}
@@ -57,7 +61,7 @@ class RuleActivationContext {
return ruleParams.values();
}
- RuleActivationContext setRuleParams(Collection<RuleParamDto> ruleParams) {
+ RuleActivatorContext setRuleParams(Collection<RuleParamDto> ruleParams) {
this.ruleParams.clear();
for (RuleParamDto ruleParam : ruleParams) {
this.ruleParams.put(ruleParam.getName(), ruleParam);
@@ -69,7 +73,7 @@ class RuleActivationContext {
return profile;
}
- RuleActivationContext setProfile(QualityProfileDto profile) {
+ RuleActivatorContext setProfile(QualityProfileDto profile) {
this.profile = profile;
return this;
}
@@ -79,7 +83,7 @@ class RuleActivationContext {
return parentProfile;
}
- RuleActivationContext setParentProfile(@Nullable QualityProfileDto p) {
+ RuleActivatorContext setParentProfile(@Nullable QualityProfileDto p) {
this.parentProfile = p;
return this;
}
@@ -89,12 +93,12 @@ class RuleActivationContext {
return activeRule;
}
- RuleActivationContext setActiveRule(@Nullable ActiveRuleDto a) {
+ RuleActivatorContext setActiveRule(@Nullable ActiveRuleDto a) {
this.activeRule = a;
return this;
}
- RuleActivationContext setParentActiveRule(@Nullable ActiveRuleDto a) {
+ RuleActivatorContext setParentActiveRule(@Nullable ActiveRuleDto a) {
this.parentActiveRule = a;
return this;
}
@@ -117,7 +121,7 @@ class RuleActivationContext {
return activeRuleParams.values();
}
- RuleActivationContext setActiveRuleParams(@Nullable Collection<ActiveRuleParamDto> a) {
+ RuleActivatorContext setActiveRuleParams(@Nullable Collection<ActiveRuleParamDto> a) {
activeRuleParams.clear();
if (a != null) {
for (ActiveRuleParamDto ar : a) {
@@ -127,7 +131,7 @@ class RuleActivationContext {
return this;
}
- RuleActivationContext setParentActiveRuleParams(@Nullable Collection<ActiveRuleParamDto> a) {
+ RuleActivatorContext setParentActiveRuleParams(@Nullable Collection<ActiveRuleParamDto> a) {
parentActiveRuleParams.clear();
if (a != null) {
for (ActiveRuleParamDto ar : a) {
@@ -169,4 +173,20 @@ class RuleActivationContext {
}
return false;
}
+
+ void verifyForActivation() {
+ if (RuleStatus.REMOVED == rule.getStatus()) {
+ throw new BadRequestException("Rule was removed: " + rule.getKey());
+ }
+ if (Cardinality.MULTIPLE.equals(rule.getCardinality())) {
+ throw new BadRequestException("Rule template can't be activated on a Quality profile: " + rule.getKey());
+ }
+ if (Rule.MANUAL_REPOSITORY_KEY.equals(rule.getRepositoryKey())) {
+ throw new BadRequestException("Manual rule can't be activated on a Quality profile: " + rule.getKey());
+ }
+ if (!profile.getLanguage().equals(rule.getLanguage())) {
+ throw new BadRequestException(String.format("Rule %s and profile %s have different languages", rule.getKey(), profile.getKey()));
+ }
+
+ }
}
diff --git a/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivationContextFactory.java b/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivatorContextFactory.java
index 02a32f3e891..57e35e1327c 100644
--- a/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivationContextFactory.java
+++ b/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivatorContextFactory.java
@@ -21,8 +21,6 @@ package org.sonar.server.qualityprofile;
import org.sonar.api.ServerComponent;
import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rule.RuleStatus;
-import org.sonar.check.Cardinality;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.qualityprofile.db.ActiveRuleDto;
import org.sonar.core.qualityprofile.db.ActiveRuleKey;
@@ -32,28 +30,24 @@ import org.sonar.core.qualityprofile.db.QualityProfileKey;
import org.sonar.core.rule.RuleDto;
import org.sonar.server.db.DbClient;
import org.sonar.server.exceptions.BadRequestException;
-import org.sonar.server.rule.Rule;
import java.util.Collection;
-public class RuleActivationContextFactory implements ServerComponent {
+public class RuleActivatorContextFactory implements ServerComponent {
private final DbClient db;
- public RuleActivationContextFactory(DbClient db) {
+ public RuleActivatorContextFactory(DbClient db) {
this.db = db;
}
- public RuleActivationContext create(ActiveRuleKey key, DbSession session) {
- RuleActivationContext context = new RuleActivationContext();
+ public RuleActivatorContext create(ActiveRuleKey key, DbSession session) {
+ RuleActivatorContext context = new RuleActivatorContext();
RuleDto rule = initRule(key.ruleKey(), context, session);
QualityProfileDto profile = initProfile(key, context, session, false);
initActiveRules(key, context, session, false);
- if (!profile.getLanguage().equals(rule.getLanguage())) {
- throw new BadRequestException(String.format("Rule %s and profile %s have different languages", rule.getKey(), profile.getKey()));
- }
if (profile.getParent() != null) {
ActiveRuleKey parentKey = ActiveRuleKey.of(
@@ -64,26 +58,17 @@ public class RuleActivationContextFactory implements ServerComponent {
return context;
}
- private RuleDto initRule(RuleKey ruleKey, RuleActivationContext context, DbSession dbSession) {
+ private RuleDto initRule(RuleKey ruleKey, RuleActivatorContext context, DbSession dbSession) {
RuleDto rule = db.ruleDao().getNullableByKey(dbSession, ruleKey);
if (rule == null) {
throw new BadRequestException("Rule not found: " + ruleKey);
}
- if (RuleStatus.REMOVED == rule.getStatus()) {
- throw new BadRequestException("Rule was removed: " + ruleKey);
- }
- if (Cardinality.MULTIPLE.equals(rule.getCardinality())) {
- throw new BadRequestException("Rule template can't be activated on a Quality profile: " + ruleKey);
- }
- if (Rule.MANUAL_REPOSITORY_KEY.equals(rule.getRepositoryKey())) {
- throw new BadRequestException("Manual rule can't be activated on a Quality profile: " + ruleKey);
- }
context.setRule(rule);
context.setRuleParams(db.ruleDao().findRuleParamsByRuleKey(dbSession, rule.getKey()));
return rule;
}
- private QualityProfileDto initProfile(ActiveRuleKey key, RuleActivationContext context, DbSession session, boolean parent) {
+ private QualityProfileDto initProfile(ActiveRuleKey key, RuleActivatorContext context, DbSession session, boolean parent) {
QualityProfileDto profile = db.qualityProfileDao().getByKey(session, key.qProfile());
if (profile == null) {
throw new BadRequestException("Quality profile not found: " + key.qProfile());
@@ -96,7 +81,7 @@ public class RuleActivationContextFactory implements ServerComponent {
return profile;
}
- private void initActiveRules(ActiveRuleKey key, RuleActivationContext context, DbSession session, boolean parent) {
+ private void initActiveRules(ActiveRuleKey key, RuleActivatorContext context, DbSession session, boolean parent) {
ActiveRuleDto activeRule = db.activeRuleDao().getNullableByKey(session, key);
Collection<ActiveRuleParamDto> activeRuleParams = null;
if (activeRule != null) {
diff --git a/sonar-server/src/main/java/org/sonar/server/rule/RegisterRules.java b/sonar-server/src/main/java/org/sonar/server/rule/RegisterRules.java
index 1cf13c34b69..d0d69ea2349 100644
--- a/sonar-server/src/main/java/org/sonar/server/rule/RegisterRules.java
+++ b/sonar-server/src/main/java/org/sonar/server/rule/RegisterRules.java
@@ -41,16 +41,19 @@ import org.sonar.core.rule.RuleParamDto;
import org.sonar.core.technicaldebt.db.CharacteristicDao;
import org.sonar.core.technicaldebt.db.CharacteristicDto;
import org.sonar.server.db.DbClient;
-import org.sonar.server.qualityprofile.ActiveRule;
-import org.sonar.server.qualityprofile.QProfileService;
+import org.sonar.server.qualityprofile.RuleActivator;
import org.sonar.server.search.IndexDefinition;
import org.sonar.server.search.action.EmbeddedIndexAction;
import org.sonar.server.search.action.IndexAction;
import org.sonar.server.search.action.KeyIndexAction;
import javax.annotation.Nullable;
-
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import static com.google.common.collect.Lists.newArrayList;
@@ -62,22 +65,22 @@ public class RegisterRules implements Startable {
private static final Logger LOG = LoggerFactory.getLogger(RegisterRules.class);
private final RuleDefinitionsLoader defLoader;
- private final QProfileService profileService;
+ private final RuleActivator ruleActivator;
private final DbClient dbClient;
private final CharacteristicDao characteristicDao;
- public RegisterRules(RuleDefinitionsLoader defLoader, QProfileService profileService,
+ public RegisterRules(RuleDefinitionsLoader defLoader, RuleActivator ruleActivator,
DbClient dbClient) {
- this(defLoader, profileService, dbClient, System2.INSTANCE);
+ this(defLoader, ruleActivator, dbClient, System2.INSTANCE);
}
@VisibleForTesting
- RegisterRules(RuleDefinitionsLoader defLoader, QProfileService profileService,
+ RegisterRules(RuleDefinitionsLoader defLoader, RuleActivator ruleActivator,
DbClient dbClient, System2 system) {
this.defLoader = defLoader;
- this.profileService = profileService;
+ this.ruleActivator = ruleActivator;
this.dbClient = dbClient;
this.characteristicDao = dbClient.debtCharacteristicDao();
}
@@ -392,10 +395,7 @@ public class RegisterRules implements Startable {
for (RuleDto rule : removedRules) {
// SONAR-4642 Remove active rules only when repository still exists
if (repositoryKeys.contains(rule.getRepositoryKey())) {
- List<ActiveRule> activeRules = profileService.findActiveRulesByRule(rule.getKey());
- for (ActiveRule activeRule : activeRules) {
- profileService.deactivate(activeRule.key());
- }
+ ruleActivator.deactivate(rule);
}
}
}
diff --git a/sonar-server/src/test/java/org/sonar/server/qualityprofile/RuleActivatorMediumTest.java b/sonar-server/src/test/java/org/sonar/server/qualityprofile/RuleActivatorMediumTest.java
index 2c03d7d7a65..f894d5b42da 100644
--- a/sonar-server/src/test/java/org/sonar/server/qualityprofile/RuleActivatorMediumTest.java
+++ b/sonar-server/src/test/java/org/sonar/server/qualityprofile/RuleActivatorMediumTest.java
@@ -20,7 +20,6 @@
package org.sonar.server.qualityprofile;
import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Multimap;
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
@@ -49,6 +48,8 @@ import org.sonar.server.search.QueryOptions;
import org.sonar.server.tester.ServerTester;
import javax.annotation.Nullable;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -62,6 +63,7 @@ public class RuleActivatorMediumTest {
static final QualityProfileKey XOO_GRAND_CHILD_PROFILE_KEY = QualityProfileKey.of("P3", "xoo");
static final RuleKey MANUAL_RULE_KEY = RuleKey.of(Rule.MANUAL_REPOSITORY_KEY, "m1");
static final RuleKey XOO_RULE_1 = RuleKey.of("xoo", "x1");
+ static final RuleKey XOO_RULE_2 = RuleKey.of("xoo", "x2");
@ClassRule
public static ServerTester tester = new ServerTester();
@@ -84,10 +86,11 @@ public class RuleActivatorMediumTest {
.setSeverity("MAJOR").setLanguage("java");
RuleDto xooRule1 = RuleTesting.newDto(XOO_RULE_1)
.setSeverity("MINOR").setLanguage("xoo");
+ RuleDto xooRule2 = RuleTesting.newDto(XOO_RULE_2).setLanguage("xoo");
RuleDto xooTemplateRule1 = RuleTesting.newDto(RuleKey.of("xoo", "template1"))
.setSeverity("MINOR").setLanguage("xoo").setCardinality(Cardinality.MULTIPLE);
RuleDto manualRule = RuleTesting.newDto(MANUAL_RULE_KEY);
- db.ruleDao().insert(dbSession, javaRule, xooRule1, xooTemplateRule1, manualRule);
+ db.ruleDao().insert(dbSession, javaRule, xooRule1, xooRule2, xooTemplateRule1, manualRule);
db.ruleDao().addRuleParam(dbSession, xooRule1, RuleParamDto.createFor(xooRule1)
.setName("max").setDefaultValue("10").setType(RuleParamType.INTEGER.type()));
db.ruleDao().addRuleParam(dbSession, xooRule1, RuleParamDto.createFor(xooRule1)
@@ -106,45 +109,53 @@ public class RuleActivatorMediumTest {
@Test
public void activate() throws Exception {
- RuleActivation activation = new RuleActivation(ActiveRuleKey.of(XOO_PROFILE_KEY, XOO_RULE_1));
+ ActiveRuleKey activeRuleKey = ActiveRuleKey.of(XOO_PROFILE_KEY, XOO_RULE_1);
+ RuleActivation activation = new RuleActivation(activeRuleKey);
activation.setSeverity(Severity.BLOCKER);
activation.setParameter("max", "7");
ruleActivator.activate(activation);
- verifyOneActiveRule(XOO_PROFILE_KEY, Severity.BLOCKER, null, ImmutableMap.of("max", "7"));
+ assertThat(countActiveRules(XOO_PROFILE_KEY)).isEqualTo(1);
+ verifyHasActiveRule(activeRuleKey, Severity.BLOCKER, null, ImmutableMap.of("max", "7"));
}
@Test
public void activate_with_default_severity_and_parameter() throws Exception {
- RuleActivation activation = new RuleActivation(ActiveRuleKey.of(XOO_PROFILE_KEY, XOO_RULE_1));
+ ActiveRuleKey activeRuleKey = ActiveRuleKey.of(XOO_PROFILE_KEY, XOO_RULE_1);
+ RuleActivation activation = new RuleActivation(activeRuleKey);
ruleActivator.activate(activation);
- verifyOneActiveRule(XOO_PROFILE_KEY, Severity.MINOR, null, ImmutableMap.of("max", "10"));
+ assertThat(countActiveRules(XOO_PROFILE_KEY)).isEqualTo(1);
+ verifyHasActiveRule(activeRuleKey, Severity.MINOR, null, ImmutableMap.of("max", "10"));
}
@Test
public void activation_ignores_unsupported_parameters() throws Exception {
- RuleActivation activation = new RuleActivation(ActiveRuleKey.of(XOO_PROFILE_KEY, XOO_RULE_1));
+ ActiveRuleKey activeRuleKey = ActiveRuleKey.of(XOO_PROFILE_KEY, XOO_RULE_1);
+ RuleActivation activation = new RuleActivation(activeRuleKey);
activation.setParameter("xxx", "yyy");
ruleActivator.activate(activation);
- verifyOneActiveRule(XOO_PROFILE_KEY, Severity.MINOR, null, ImmutableMap.of("max", "10"));
+ assertThat(countActiveRules(XOO_PROFILE_KEY)).isEqualTo(1);
+ verifyHasActiveRule(activeRuleKey, Severity.MINOR, null, ImmutableMap.of("max", "10"));
}
@Test
public void update_activation_severity_and_parameters() throws Exception {
// initial activation
- RuleActivation activation = new RuleActivation(ActiveRuleKey.of(XOO_PROFILE_KEY, XOO_RULE_1));
+ ActiveRuleKey activeRuleKey = ActiveRuleKey.of(XOO_PROFILE_KEY, XOO_RULE_1);
+ RuleActivation activation = new RuleActivation(activeRuleKey);
activation.setSeverity(Severity.BLOCKER);
ruleActivator.activate(activation);
// update
- RuleActivation update = new RuleActivation(ActiveRuleKey.of(XOO_PROFILE_KEY, XOO_RULE_1));
+ RuleActivation update = new RuleActivation(activeRuleKey);
update.setSeverity(Severity.CRITICAL);
update.setParameter("max", "42");
ruleActivator.activate(update);
- verifyOneActiveRule(XOO_PROFILE_KEY, Severity.CRITICAL, null, ImmutableMap.of("max", "42"));
+ assertThat(countActiveRules(XOO_PROFILE_KEY)).isEqualTo(1);
+ verifyHasActiveRule(activeRuleKey, Severity.CRITICAL, null, ImmutableMap.of("max", "42"));
}
@Test
@@ -169,22 +180,25 @@ public class RuleActivatorMediumTest {
// contrary to activerule, the param 'max' is supposed to be inserted but not updated
ruleActivator.activate(update);
- verifyOneActiveRule(XOO_PROFILE_KEY, Severity.CRITICAL, null, ImmutableMap.of("max", "42"));
+ assertThat(countActiveRules(XOO_PROFILE_KEY)).isEqualTo(1);
+ verifyHasActiveRule(activeRuleKey, Severity.CRITICAL, null, ImmutableMap.of("max", "42"));
}
@Test
public void revert_activation_to_default_severity_and_parameters() throws Exception {
// initial activation
- RuleActivation activation = new RuleActivation(ActiveRuleKey.of(XOO_PROFILE_KEY, XOO_RULE_1));
+ ActiveRuleKey activeRuleKey = ActiveRuleKey.of(XOO_PROFILE_KEY, XOO_RULE_1);
+ RuleActivation activation = new RuleActivation(activeRuleKey);
activation.setSeverity(Severity.BLOCKER);
activation.setParameter("max", "7");
ruleActivator.activate(activation);
// update
- RuleActivation update = new RuleActivation(ActiveRuleKey.of(XOO_PROFILE_KEY, XOO_RULE_1));
+ RuleActivation update = new RuleActivation(activeRuleKey);
ruleActivator.activate(update);
- verifyOneActiveRule(XOO_PROFILE_KEY, Severity.MINOR, null, ImmutableMap.of("max", "10"));
+ assertThat(countActiveRules(XOO_PROFILE_KEY)).isEqualTo(1);
+ verifyHasActiveRule(activeRuleKey, Severity.MINOR, null, ImmutableMap.of("max", "10"));
}
@Test
@@ -334,6 +348,26 @@ public class RuleActivatorMediumTest {
}
}
+ @Test
+ public void allow_to_deactivate_removed_rule() throws Exception {
+ // activation
+ ActiveRuleKey key = ActiveRuleKey.of(XOO_PROFILE_KEY, XOO_RULE_1);
+ RuleActivation activation = new RuleActivation(key);
+ ruleActivator.activate(activation);
+
+ // set rule as removed
+ RuleDto rule = db.ruleDao().getByKey(dbSession, XOO_RULE_1);
+ rule.setStatus(RuleStatus.REMOVED);
+ db.ruleDao().update(dbSession, rule);
+ dbSession.commit();
+ dbSession.clearCache();
+
+ // deactivation
+ ruleActivator.deactivate(key);
+
+ verifyZeroActiveRules(XOO_PROFILE_KEY);
+ }
+
// INHERITANCE OF PROFILES
@Test
public void activate_on_child_profile() throws Exception {
@@ -346,8 +380,8 @@ public class RuleActivatorMediumTest {
ruleActivator.activate(activation);
verifyZeroActiveRules(XOO_PROFILE_KEY);
- verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, Severity.BLOCKER, null, ImmutableMap.of("max", "7"));
- verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, null, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
}
@Test
@@ -360,9 +394,9 @@ public class RuleActivatorMediumTest {
activation.setParameter("max", "7");
ruleActivator.activate(activation);
- verifyOneActiveRule(XOO_PROFILE_KEY, Severity.BLOCKER, null, ImmutableMap.of("max", "7"));
- verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
- verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, null, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
}
@Test
@@ -374,9 +408,9 @@ public class RuleActivatorMediumTest {
activation.setSeverity(Severity.BLOCKER);
activation.setParameter("max", "7");
ruleActivator.activate(activation);
- verifyOneActiveRule(XOO_PROFILE_KEY, Severity.BLOCKER, null, ImmutableMap.of("max", "7"));
- verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
- verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, null, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
// update on parent
activation = new RuleActivation(ActiveRuleKey.of(XOO_PROFILE_KEY, XOO_RULE_1));
@@ -384,9 +418,9 @@ public class RuleActivatorMediumTest {
activation.setParameter("max", "8");
ruleActivator.activate(activation);
dbSession.clearCache();
- verifyOneActiveRule(XOO_PROFILE_KEY, Severity.INFO, null, ImmutableMap.of("max", "8"));
- verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, Severity.INFO, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "8"));
- verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, Severity.INFO, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "8"));
+ verifyOneActiveRule(XOO_PROFILE_KEY, XOO_RULE_1, Severity.INFO, null, ImmutableMap.of("max", "8"));
+ verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.INFO, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "8"));
+ verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.INFO, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "8"));
// update on child -> propagate on grand child only
activation = new RuleActivation(ActiveRuleKey.of(XOO_CHILD_PROFILE_KEY, XOO_RULE_1));
@@ -394,9 +428,9 @@ public class RuleActivatorMediumTest {
activation.setParameter("max", "9");
ruleActivator.activate(activation);
dbSession.clearCache();
- verifyOneActiveRule(XOO_PROFILE_KEY, Severity.INFO, null, ImmutableMap.of("max", "8"));
- verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, Severity.MINOR, ActiveRuleDto.OVERRIDES, ImmutableMap.of("max", "9"));
- verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, Severity.MINOR, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "9"));
+ verifyOneActiveRule(XOO_PROFILE_KEY, XOO_RULE_1, Severity.INFO, null, ImmutableMap.of("max", "8"));
+ verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.MINOR, ActiveRuleDto.OVERRIDES, ImmutableMap.of("max", "9"));
+ verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.MINOR, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "9"));
// update on grand child
activation = new RuleActivation(ActiveRuleKey.of(XOO_GRAND_CHILD_PROFILE_KEY, XOO_RULE_1));
@@ -404,9 +438,9 @@ public class RuleActivatorMediumTest {
activation.setParameter("max", "10");
ruleActivator.activate(activation);
dbSession.clearCache();
- verifyOneActiveRule(XOO_PROFILE_KEY, Severity.INFO, null, ImmutableMap.of("max", "8"));
- verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, Severity.MINOR, ActiveRuleDto.OVERRIDES, ImmutableMap.of("max", "9"));
- verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, Severity.BLOCKER, ActiveRuleDto.OVERRIDES, ImmutableMap.of("max", "10"));
+ verifyOneActiveRule(XOO_PROFILE_KEY, XOO_RULE_1, Severity.INFO, null, ImmutableMap.of("max", "8"));
+ verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.MINOR, ActiveRuleDto.OVERRIDES, ImmutableMap.of("max", "9"));
+ verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, ActiveRuleDto.OVERRIDES, ImmutableMap.of("max", "10"));
}
@Test
@@ -418,9 +452,9 @@ public class RuleActivatorMediumTest {
activation.setSeverity(Severity.INFO);
activation.setParameter("max", "7");
ruleActivator.activate(activation);
- verifyOneActiveRule(XOO_PROFILE_KEY, Severity.INFO, null, ImmutableMap.of("max", "7"));
- verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, Severity.INFO, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
- verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, Severity.INFO, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_PROFILE_KEY, XOO_RULE_1, Severity.INFO, null, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.INFO, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.INFO, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
// override on child
activation = new RuleActivation(ActiveRuleKey.of(XOO_CHILD_PROFILE_KEY, XOO_RULE_1));
@@ -428,9 +462,9 @@ public class RuleActivatorMediumTest {
activation.setParameter("max", "8");
ruleActivator.activate(activation);
dbSession.clearCache();
- verifyOneActiveRule(XOO_PROFILE_KEY, Severity.INFO, null, ImmutableMap.of("max", "7"));
- verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, Severity.BLOCKER, ActiveRuleDto.OVERRIDES, ImmutableMap.of("max", "8"));
- verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "8"));
+ verifyOneActiveRule(XOO_PROFILE_KEY, XOO_RULE_1, Severity.INFO, null, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, ActiveRuleDto.OVERRIDES, ImmutableMap.of("max", "8"));
+ verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "8"));
// change on parent -> do not propagate on children because they're overriding values
activation = new RuleActivation(ActiveRuleKey.of(XOO_PROFILE_KEY, XOO_RULE_1));
@@ -438,9 +472,9 @@ public class RuleActivatorMediumTest {
activation.setParameter("max", "10");
ruleActivator.activate(activation);
dbSession.clearCache();
- verifyOneActiveRule(XOO_PROFILE_KEY, Severity.CRITICAL, null, ImmutableMap.of("max", "10"));
- verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, Severity.BLOCKER, ActiveRuleDto.OVERRIDES, ImmutableMap.of("max", "8"));
- verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "8"));
+ verifyOneActiveRule(XOO_PROFILE_KEY, XOO_RULE_1, Severity.CRITICAL, null, ImmutableMap.of("max", "10"));
+ verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, ActiveRuleDto.OVERRIDES, ImmutableMap.of("max", "8"));
+ verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "8"));
}
@Test
@@ -452,8 +486,8 @@ public class RuleActivatorMediumTest {
activation.setSeverity(Severity.INFO);
activation.setParameter("max", "7");
ruleActivator.activate(activation);
- verifyOneActiveRule(XOO_PROFILE_KEY, Severity.INFO, null, ImmutableMap.of("max", "7"));
- verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, Severity.INFO, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_PROFILE_KEY, XOO_RULE_1, Severity.INFO, null, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.INFO, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
// override on child with same severity and params -> do nothing (still INHERITED but not OVERRIDDEN)
activation = new RuleActivation(ActiveRuleKey.of(XOO_CHILD_PROFILE_KEY, XOO_RULE_1));
@@ -461,8 +495,8 @@ public class RuleActivatorMediumTest {
activation.setParameter("max", "7");
ruleActivator.activate(activation);
dbSession.clearCache();
- verifyOneActiveRule(XOO_PROFILE_KEY, Severity.INFO, null, ImmutableMap.of("max", "7"));
- verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, Severity.INFO, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_PROFILE_KEY, XOO_RULE_1, Severity.INFO, null, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.INFO, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
}
@Test
@@ -474,9 +508,9 @@ public class RuleActivatorMediumTest {
activation.setSeverity(Severity.BLOCKER);
activation.setParameter("max", "7");
ruleActivator.activate(activation);
- verifyOneActiveRule(XOO_PROFILE_KEY, Severity.BLOCKER, null, ImmutableMap.of("max", "7"));
- verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
- verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, null, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
// deactivate on root
ruleActivator.deactivate(activation.getKey());
@@ -495,9 +529,9 @@ public class RuleActivatorMediumTest {
activation.setSeverity(Severity.BLOCKER);
activation.setParameter("max", "7");
ruleActivator.activate(activation);
- verifyOneActiveRule(XOO_PROFILE_KEY, Severity.BLOCKER, null, ImmutableMap.of("max", "7"));
- verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
- verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, null, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
// try to deactivate on child
try {
@@ -517,9 +551,9 @@ public class RuleActivatorMediumTest {
activation.setSeverity(Severity.BLOCKER);
activation.setParameter("max", "7");
ruleActivator.activate(activation);
- verifyOneActiveRule(XOO_PROFILE_KEY, Severity.BLOCKER, null, ImmutableMap.of("max", "7"));
- verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
- verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, null, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
// override
activation = new RuleActivation(ActiveRuleKey.of(XOO_CHILD_PROFILE_KEY, XOO_RULE_1));
@@ -527,17 +561,17 @@ public class RuleActivatorMediumTest {
activation.setParameter("max", "10");
ruleActivator.activate(activation);
dbSession.clearCache();
- verifyOneActiveRule(XOO_PROFILE_KEY, Severity.BLOCKER, null, ImmutableMap.of("max", "7"));
- verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, Severity.INFO, ActiveRuleDto.OVERRIDES, ImmutableMap.of("max", "10"));
- verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, Severity.INFO, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "10"));
+ verifyOneActiveRule(XOO_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, null, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.INFO, ActiveRuleDto.OVERRIDES, ImmutableMap.of("max", "10"));
+ verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.INFO, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "10"));
// reset -> remove overridden values
activation = new RuleActivation(ActiveRuleKey.of(XOO_CHILD_PROFILE_KEY, XOO_RULE_1));
ruleActivator.activate(activation);
dbSession.clearCache();
- verifyOneActiveRule(XOO_PROFILE_KEY, Severity.BLOCKER, null, ImmutableMap.of("max", "7"));
- verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
- verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, null, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
}
@Test
@@ -549,9 +583,9 @@ public class RuleActivatorMediumTest {
activation.setSeverity(Severity.BLOCKER);
activation.setParameter("max", "7");
ruleActivator.activate(activation);
- verifyOneActiveRule(XOO_PROFILE_KEY, Severity.BLOCKER, null, ImmutableMap.of("max", "7"));
- verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
- verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, null, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
// override on child
activation = new RuleActivation(ActiveRuleKey.of(XOO_CHILD_PROFILE_KEY, XOO_RULE_1));
@@ -559,9 +593,9 @@ public class RuleActivatorMediumTest {
activation.setParameter("max", "10");
ruleActivator.activate(activation);
dbSession.clearCache();
- verifyOneActiveRule(XOO_PROFILE_KEY, Severity.BLOCKER, null, ImmutableMap.of("max", "7"));
- verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, Severity.INFO, ActiveRuleDto.OVERRIDES, ImmutableMap.of("max", "10"));
- verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, Severity.INFO, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "10"));
+ verifyOneActiveRule(XOO_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, null, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.INFO, ActiveRuleDto.OVERRIDES, ImmutableMap.of("max", "10"));
+ verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.INFO, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "10"));
// override on grand child
activation = new RuleActivation(ActiveRuleKey.of(XOO_GRAND_CHILD_PROFILE_KEY, XOO_RULE_1));
@@ -569,43 +603,37 @@ public class RuleActivatorMediumTest {
activation.setParameter("max", "20");
ruleActivator.activate(activation);
dbSession.clearCache();
- verifyOneActiveRule(XOO_PROFILE_KEY, Severity.BLOCKER, null, ImmutableMap.of("max", "7"));
- verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, Severity.INFO, ActiveRuleDto.OVERRIDES, ImmutableMap.of("max", "10"));
- verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, Severity.MINOR, ActiveRuleDto.OVERRIDES, ImmutableMap.of("max", "20"));
+ verifyOneActiveRule(XOO_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, null, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.INFO, ActiveRuleDto.OVERRIDES, ImmutableMap.of("max", "10"));
+ verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.MINOR, ActiveRuleDto.OVERRIDES, ImmutableMap.of("max", "20"));
// reset child -> keep the overridden grand-child
activation = new RuleActivation(ActiveRuleKey.of(XOO_CHILD_PROFILE_KEY, XOO_RULE_1));
ruleActivator.activate(activation);
dbSession.clearCache();
- verifyOneActiveRule(XOO_PROFILE_KEY, Severity.BLOCKER, null, ImmutableMap.of("max", "7"));
- verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
- verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, Severity.MINOR, ActiveRuleDto.OVERRIDES, ImmutableMap.of("max", "20"));
+ verifyOneActiveRule(XOO_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, null, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.BLOCKER, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "7"));
+ verifyOneActiveRule(XOO_GRAND_CHILD_PROFILE_KEY, XOO_RULE_1, Severity.MINOR, ActiveRuleDto.OVERRIDES, ImmutableMap.of("max", "20"));
}
@Test
- public void bulk_activate() {
-
+ public void bulk_activate_lot_of_rules() {
// Generate more rules than the search's max limit
int bulkSize = QueryOptions.MAX_LIMIT + 10;
for (int i = 0; i < bulkSize; i++) {
- db.ruleDao().insert(dbSession, RuleDto.createFor(
- RuleKey.of("bulk", "r_" + i))
- .setLanguage("xoo")
- .setSeverity("BLOCKER")
- .setStatus(RuleStatus.READY));
+ db.ruleDao().insert(dbSession, RuleTesting.newDto(RuleKey.of("bulk", "r_" + i)).setLanguage("xoo"));
}
dbSession.commit();
// 0. No active rules so far (base case) and plenty rules available
verifyZeroActiveRules(XOO_PROFILE_KEY);
assertThat(tester.get(RuleIndex.class)
- .search(new RuleQuery().setQueryText("bulk"), new QueryOptions()).getTotal())
+ .search(new RuleQuery().setRepositories(Arrays.asList("bulk")), new QueryOptions()).getTotal())
.isEqualTo(bulkSize);
- // 1. assert that bulk activate generates all Activation
- Multimap<String, String> result = ruleActivator.bulkActivate(
- new RuleQuery().setQueryText("bulk"), XOO_PROFILE_KEY, "MINOR");
-// assertThat(result.get(RuleActivator.ACTIVATED)).hasSize(bulkSize);
+ // 1. bulk activate all the rules
+ ruleActivator.bulkActivate(
+ new RuleQuery().setRepositories(Arrays.asList("bulk")), XOO_PROFILE_KEY, "MINOR");
// 2. assert that all activation has been commited to DB and ES
dbSession.clearCache();
@@ -614,38 +642,126 @@ public class RuleActivatorMediumTest {
}
- private void verifyOneActiveRule(QualityProfileKey profileKey, String expectedSeverity,
+ @Test
+ public void set_and_unset_parent_profile() {
+ // x1 is activated on the "future parent"
+ RuleActivation activation = new RuleActivation(ActiveRuleKey.of(XOO_PROFILE_KEY, XOO_RULE_1));
+ activation.setSeverity("MAJOR");
+ ruleActivator.activate(activation);
+ verifyOneActiveRule(XOO_PROFILE_KEY, XOO_RULE_1, Severity.MAJOR, null, ImmutableMap.of("max", "10"));
+
+ // create profile with x2
+ QualityProfileKey childKey = QualityProfileKey.of("newChild", "xoo");
+ db.qualityProfileDao().insert(dbSession, QualityProfileDto.createFor(childKey));
+ activation = new RuleActivation(ActiveRuleKey.of(childKey, XOO_RULE_2));
+ activation.setSeverity("MAJOR");
+ ruleActivator.activate(dbSession, activation);
+ dbSession.commit();
+ dbSession.clearCache();
+
+ // set parent -> child profile inherits rule x1 and still has x2
+ ruleActivator.setParent(childKey, XOO_PROFILE_KEY);
+ assertThat(db.qualityProfileDao().getByKey(dbSession, childKey).getParentKey()).isEqualTo(XOO_PROFILE_KEY);
+ verifyHasActiveRule(ActiveRuleKey.of(childKey, XOO_RULE_1), Severity.MAJOR, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "10"));
+ verifyHasActiveRule(ActiveRuleKey.of(childKey, XOO_RULE_2), Severity.MAJOR, null, Collections.<String, String>emptyMap());
+
+ // unset parent
+ dbSession.clearCache();
+ ruleActivator.setParent(childKey, null);
+ assertThat(countActiveRules(childKey)).isEqualTo(1);
+ assertThat(db.qualityProfileDao().getByKey(dbSession, childKey).getParentKey()).isNull();
+ verifyHasActiveRule(ActiveRuleKey.of(childKey, XOO_RULE_2), Severity.MAJOR, null, Collections.<String, String>emptyMap());
+ }
+
+ @Test
+ public void keep_overridden_rules_when_unsetting_parent() {
+ // x1 is activated on the "future parent"
+ RuleActivation activation = new RuleActivation(ActiveRuleKey.of(XOO_PROFILE_KEY, XOO_RULE_1));
+ activation.setSeverity("MAJOR");
+ ruleActivator.activate(activation);
+ verifyOneActiveRule(XOO_PROFILE_KEY, XOO_RULE_1, Severity.MAJOR, null, ImmutableMap.of("max", "10"));
+
+ // create empty profile
+ QualityProfileKey childKey = QualityProfileKey.of("newChild", "xoo");
+ db.qualityProfileDao().insert(dbSession, QualityProfileDto.createFor(childKey));
+ dbSession.commit();
+ dbSession.clearCache();
+
+ // set parent -> child profile inherits rule x1
+ ruleActivator.setParent(childKey, XOO_PROFILE_KEY);
+ verifyOneActiveRule(childKey, XOO_RULE_1, Severity.MAJOR, ActiveRuleDto.INHERITED, ImmutableMap.of("max", "10"));
+
+ // override x1
+ activation = new RuleActivation(ActiveRuleKey.of(childKey, XOO_RULE_1));
+ activation.setSeverity("BLOCKER").setParameter("max", "333");
+ ruleActivator.activate(activation);
+ dbSession.clearCache();
+ verifyOneActiveRule(childKey, XOO_RULE_1, Severity.BLOCKER, ActiveRuleDto.OVERRIDES, ImmutableMap.of("max", "333"));
+
+ // unset parent -> keep x1
+ ruleActivator.setParent(childKey, null);
+ dbSession.clearCache();
+ assertThat(db.qualityProfileDao().getByKey(dbSession, childKey).getParentKey()).isNull();
+ verifyOneActiveRule(childKey, XOO_RULE_1, Severity.BLOCKER, null, ImmutableMap.of("max", "333"));
+ }
+
+ private int countActiveRules(QualityProfileKey profileKey) {
+ List<ActiveRuleDto> activeRuleDtos = db.activeRuleDao().findByProfileKey(dbSession, profileKey);
+ List<ActiveRule> activeRules = index.findByProfile(profileKey);
+ assertThat(activeRuleDtos.size()).as("Not same active rules between db and index").isEqualTo(activeRules.size());
+ return activeRuleDtos.size();
+ }
+
+ private void verifyOneActiveRule(QualityProfileKey profileKey, RuleKey ruleKey, String expectedSeverity,
+ @Nullable String expectedInheritance, Map<String, String> expectedParams) {
+ assertThat(countActiveRules(profileKey)).isEqualTo(1);
+ verifyHasActiveRule(profileKey, ruleKey, expectedSeverity, expectedInheritance, expectedParams);
+ }
+
+ private void verifyHasActiveRule(QualityProfileKey profileKey, RuleKey ruleKey, String expectedSeverity,
@Nullable String expectedInheritance, Map<String, String> expectedParams) {
+ verifyHasActiveRule(ActiveRuleKey.of(profileKey, ruleKey), expectedSeverity, expectedInheritance, expectedParams);
+ }
+ private void verifyHasActiveRule(ActiveRuleKey activeRuleKey, String expectedSeverity,
+ @Nullable String expectedInheritance, Map<String, String> expectedParams) {
// verify db
- List<ActiveRuleDto> activeRuleDtos = db.activeRuleDao().findByProfileKey(dbSession, profileKey);
- assertThat(activeRuleDtos).hasSize(1);
- ActiveRuleDto activeRuleDto = activeRuleDtos.get(0);
- assertThat(activeRuleDto.getSeverityString()).isEqualTo(expectedSeverity);
- assertThat(activeRuleDto.getInheritance()).isEqualTo(expectedInheritance);
-
- // verify parameters in db
- List<ActiveRuleParamDto> paramDtos = db.activeRuleDao().findParamsByActiveRuleKey(dbSession, activeRuleDto.getKey());
- assertThat(paramDtos).hasSize(expectedParams.size());
- for (Map.Entry<String, String> entry : expectedParams.entrySet()) {
- ActiveRuleParamDto paramDto = db.activeRuleDao().getParamByKeyAndName(activeRuleDto.getKey(), entry.getKey(), dbSession);
- assertThat(paramDto).isNotNull();
- assertThat(paramDto.getValue()).isEqualTo(entry.getValue());
+ boolean found = false;
+ List<ActiveRuleDto> activeRuleDtos = db.activeRuleDao().findByProfileKey(dbSession, activeRuleKey.qProfile());
+ for (ActiveRuleDto activeRuleDto : activeRuleDtos) {
+ if (activeRuleDto.getKey().equals(activeRuleKey)) {
+ found = true;
+ assertThat(activeRuleDto.getSeverityString()).isEqualTo(expectedSeverity);
+ assertThat(activeRuleDto.getInheritance()).isEqualTo(expectedInheritance);
+ List<ActiveRuleParamDto> paramDtos = db.activeRuleDao().findParamsByActiveRuleKey(dbSession, activeRuleDto.getKey());
+ assertThat(paramDtos).hasSize(expectedParams.size());
+ for (Map.Entry<String, String> entry : expectedParams.entrySet()) {
+ ActiveRuleParamDto paramDto = db.activeRuleDao().getParamByKeyAndName(activeRuleDto.getKey(), entry.getKey(), dbSession);
+ assertThat(paramDto).isNotNull();
+ assertThat(paramDto.getValue()).isEqualTo(entry.getValue());
+ }
+ }
}
+ assertThat(found).as("Rule is not activated in db").isTrue();
// verify es
- List<ActiveRule> activeRules = index.findByProfile(profileKey);
- assertThat(activeRules).hasSize(1);
- ActiveRule activeRule = activeRules.get(0);
- assertThat(activeRule.severity()).isEqualTo(expectedSeverity);
- assertThat(activeRule.inheritance()).isEqualTo(expectedInheritance == null ? ActiveRule.Inheritance.NONE : ActiveRule.Inheritance.valueOf(expectedInheritance));
-
- // verify parameters in es
- assertThat(activeRule.params()).hasSize(expectedParams.size());
- for (Map.Entry<String, String> entry : expectedParams.entrySet()) {
- String value = activeRule.params().get(entry.getKey());
- assertThat(value).isEqualTo(entry.getValue());
+ List<ActiveRule> activeRules = index.findByProfile(activeRuleKey.qProfile());
+ found = false;
+ for (ActiveRule activeRule : activeRules) {
+ if (activeRule.key().equals(activeRuleKey)) {
+ found = true;
+ assertThat(activeRule.severity()).isEqualTo(expectedSeverity);
+ assertThat(activeRule.inheritance()).isEqualTo(expectedInheritance == null ? ActiveRule.Inheritance.NONE : ActiveRule.Inheritance.valueOf(expectedInheritance));
+
+ // verify parameters in es
+ assertThat(activeRule.params()).hasSize(expectedParams.size());
+ for (Map.Entry<String, String> entry : expectedParams.entrySet()) {
+ String value = activeRule.params().get(entry.getKey());
+ assertThat(value).isEqualTo(entry.getValue());
+ }
+ }
}
+ assertThat(found).as("Rule is not activated in index").isTrue();
}
private void createChildProfiles() {
diff --git a/sonar-server/src/test/java/org/sonar/server/qualityprofile/RuleChangeTest.java b/sonar-server/src/test/java/org/sonar/server/qualityprofile/RuleChangeTest.java
deleted file mode 100644
index a962470d8c2..00000000000
--- a/sonar-server/src/test/java/org/sonar/server/qualityprofile/RuleChangeTest.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.sonar.api.rules.ActiveRuleChange;
-import org.sonar.api.rules.RulePriority;
-import org.sonar.core.preview.PreviewCache;
-import org.sonar.jpa.test.AbstractDbUnitTestCase;
-
-import static org.fest.assertions.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-
-@Deprecated
-/**
- * @deprecated Medium tests executed in RegisterRuleMediumTest
- */
-@Ignore
-public class RuleChangeTest extends AbstractDbUnitTestCase {
- private ProfilesManager profilesManager;
-
- @Before
- public void setUp() {
- profilesManager = new ProfilesManager(getSession(), mock(PreviewCache.class));
- }
-
- @Test
- public void should_increase_version_if_used() {
- setupData("initialData");
- profilesManager.activated(2, 3, "admin");
- checkTables("versionIncreaseIfUsed", "rules_profiles");
- }
-
- @Test
- public void should_track_rule_activation() {
- setupData("initialData");
- profilesManager.activated(2, 3, "admin");
- checkTables("ruleActivated", new String[]{"change_date"}, "active_rule_changes");
- }
-
- @Test
- public void should_track_rule_deactivation() {
- setupData("initialData");
- profilesManager.deactivated(2, 3, "admin");
- checkTables("ruleDeactivated", new String[]{"change_date"}, "active_rule_changes");
- }
-
- @Test
- public void should_track_rule_param_change() {
- setupData("initialData");
- profilesManager.ruleParamChanged(2, 3, "param1", "20", "30", "admin");
- checkTables("ruleParamChanged", new String[]{"change_date"}, "active_rule_changes", "active_rule_param_changes");
- }
-
- @Test
- public void should_not_track_rule_param_change_if_no_change() {
- setupData("initialData");
- profilesManager.ruleParamChanged(2, 3, "param1", "20", "20", "admin");
- assertThat(getHQLCount(ActiveRuleChange.class)).isEqualTo(0);
- }
-
- @Test
- public void should_track_rule_severity_change() {
- setupData("initialData");
- profilesManager.ruleSeverityChanged(2, 3, RulePriority.BLOCKER, RulePriority.CRITICAL, "admin");
- checkTables("ruleSeverityChanged", new String[]{"change_date"}, "active_rule_changes");
- }
-
- @Test
- public void should_not_track_rule_severity_change_if_no_change() {
- setupData("initialData");
- profilesManager.ruleSeverityChanged(2, 3, RulePriority.BLOCKER, RulePriority.BLOCKER, "admin");
- assertThat(getHQLCount(ActiveRuleChange.class)).isEqualTo(0);
- }
-
- @Test
- public void should_track_change_parent_profile() {
- setupData("changeParentProfile");
- profilesManager.profileParentChanged(2, "parent", "admin");
- checkTables("changeParentProfile", new String[]{"change_date"}, "active_rule_changes");
- }
-
-}
diff --git a/sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesMediumTest.java b/sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesMediumTest.java
index b5d3347d938..34797df5b82 100644
--- a/sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesMediumTest.java
+++ b/sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesMediumTest.java
@@ -20,21 +20,31 @@
package org.sonar.server.rule;
+import org.junit.After;
+import org.junit.Before;
import org.junit.Test;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rule.RuleStatus;
import org.sonar.api.rule.Severity;
import org.sonar.api.server.rule.RuleParamType;
import org.sonar.api.server.rule.RulesDefinition;
+import org.sonar.core.permission.GlobalPermissions;
import org.sonar.core.persistence.DbSession;
+import org.sonar.core.qualityprofile.db.ActiveRuleKey;
+import org.sonar.core.qualityprofile.db.QualityProfileDto;
+import org.sonar.core.qualityprofile.db.QualityProfileKey;
import org.sonar.core.rule.RuleDto;
import org.sonar.core.rule.RuleParamDto;
import org.sonar.server.db.DbClient;
import org.sonar.server.platform.Platform;
-import org.sonar.server.rule.db.RuleDao;
+import org.sonar.server.qualityprofile.QProfileService;
+import org.sonar.server.qualityprofile.RuleActivation;
import org.sonar.server.rule.index.RuleIndex;
import org.sonar.server.rule.index.RuleQuery;
import org.sonar.server.rule.index.RuleResult;
import org.sonar.server.search.QueryOptions;
import org.sonar.server.tester.ServerTester;
+import org.sonar.server.user.MockUserSession;
import java.util.List;
@@ -42,30 +52,55 @@ import static org.fest.assertions.Assertions.assertThat;
public class RegisterRulesMediumTest {
+ // Hack to restart server without x2
+ static boolean includeX1 = true, includeX2 = true;
+
@org.junit.Rule
public ServerTester tester = new ServerTester().addComponents(XooRulesDefinition.class);
+ DbClient db;
+ DbSession dbSession;
+
+ @Before
+ public void before() {
+ db = tester.get(DbClient.class);
+ dbSession = tester.get(DbClient.class).openSession(false);
+ }
+
+ @After
+ public void after() {
+ dbSession.close();
+ includeX1 = true;
+ includeX2 = true;
+ }
+
@Test
public void register_rules_at_startup() throws Exception {
- verifyRulesInDb();
+ verifyTwoRulesInDb();
RuleIndex index = tester.get(RuleIndex.class);
-
RuleResult searchResult = index.search(new RuleQuery(), new QueryOptions());
assertThat(searchResult.getTotal()).isEqualTo(2);
assertThat(searchResult.getHits()).hasSize(2);
}
+ /**
+ * support the use-case:
+ * 1. start server
+ * 2. stop server
+ * 3. drop elasticsearch index: rm -rf data/es
+ * 4. start server -> db is up-to-date (no changes) but rules must be re-indexed
+ */
@Test
public void index_even_if_no_changes() throws Exception {
RuleIndex index = tester.get(RuleIndex.class);
- verifyRulesInDb();
+ verifyTwoRulesInDb();
// clear ES but keep db
tester.clearIndexes();
- verifyRulesInDb();
+ verifyTwoRulesInDb();
RuleResult searchResult = index.search(new RuleQuery(), new QueryOptions());
assertThat(searchResult.getTotal()).isEqualTo(0);
assertThat(searchResult.getHits()).hasSize(0);
@@ -75,41 +110,105 @@ public class RegisterRulesMediumTest {
index = tester.get(RuleIndex.class);
- verifyRulesInDb();
+ verifyTwoRulesInDb();
searchResult = index.search(new RuleQuery().setKey("xoo:x1"), new QueryOptions());
assertThat(searchResult.getTotal()).isEqualTo(1);
assertThat(searchResult.getHits()).hasSize(1);
assertThat(searchResult.getHits().get(0).params()).hasSize(1);
}
- private void verifyRulesInDb() {
- RuleDao dao = tester.get(RuleDao.class);
- DbClient dbClient = tester.get(DbClient.class);
- DbSession session = dbClient.openSession(false);
- List<RuleDto> rules = dao.findAll(session);
+ @Test
+ public void mark_rule_as_removed() throws Exception {
+ verifyTwoRulesInDb();
+
+ includeX2 = false;
+ tester.get(Platform.class).restart();
+
+ verifyTwoRulesInDb();
+ RuleDto rule = db.ruleDao().getByKey(dbSession, RuleKey.of("xoo", "x2"));
+ assertThat(rule.getStatus()).isEqualTo(RuleStatus.REMOVED);
+ }
+
+ @Test
+ public void deactivate_removed_rules_only_if_repository_still_exists() throws Exception {
+ MockUserSession.set().setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN).setLogin("me");
+
+ // create a profile and activate rule
+ QualityProfileKey profileKey = QualityProfileKey.of("P1", "xoo");
+ db.qualityProfileDao().insert(dbSession, QualityProfileDto.createFor(profileKey));
+ dbSession.commit();
+ dbSession.clearCache();
+ ActiveRuleKey activeRuleKey = ActiveRuleKey.of(profileKey, RuleKey.of("xoo", "x1"));
+ RuleActivation activation = new RuleActivation(activeRuleKey);
+ tester.get(QProfileService.class).activate(activation);
+ dbSession.clearCache();
+
+ // restart, x2 still exists -> deactivate x1
+ includeX1 = false;
+ includeX2 = true;
+ tester.get(Platform.class).restart();
+ dbSession.clearCache();
+ assertThat(db.ruleDao().getByKey(dbSession, RuleKey.of("xoo", "x1")).getStatus()).isEqualTo(RuleStatus.REMOVED);
+ assertThat(db.ruleDao().getByKey(dbSession, RuleKey.of("xoo", "x2")).getStatus()).isEqualTo(RuleStatus.READY);
+ assertThat(db.activeRuleDao().findByProfileKey(dbSession, profileKey)).hasSize(0);
+ }
+
+ @Test
+ public void do_not_deactivate_removed_rules_if_repository_accidentaly_uninstalled() throws Exception {
+ MockUserSession.set().setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN).setLogin("me");
+
+ // create a profile and activate rule
+ QualityProfileKey profileKey = QualityProfileKey.of("P1", "xoo");
+ db.qualityProfileDao().insert(dbSession, QualityProfileDto.createFor(profileKey));
+ dbSession.commit();
+ dbSession.clearCache();
+ ActiveRuleKey activeRuleKey = ActiveRuleKey.of(profileKey, RuleKey.of("xoo", "x1"));
+ RuleActivation activation = new RuleActivation(activeRuleKey);
+ tester.get(QProfileService.class).activate(activation);
+ dbSession.clearCache();
+
+ // restart without x1 and x2 -> keep active rule of x1
+ includeX1 = false;
+ includeX2 = false;
+ tester.get(Platform.class).restart();
+ dbSession.clearCache();
+ assertThat(db.ruleDao().getByKey(dbSession, RuleKey.of("xoo", "x1")).getStatus()).isEqualTo(RuleStatus.REMOVED);
+ assertThat(db.ruleDao().getByKey(dbSession, RuleKey.of("xoo", "x2")).getStatus()).isEqualTo(RuleStatus.REMOVED);
+ assertThat(db.activeRuleDao().findByProfileKey(dbSession, profileKey)).hasSize(1);
+ }
+
+ private void verifyTwoRulesInDb() {
+ List<RuleDto> rules = db.ruleDao().findAll(dbSession);
assertThat(rules).hasSize(2);
- List<RuleParamDto> ruleParams = dao.findAllRuleParams(session);
+ List<RuleParamDto> ruleParams = db.ruleDao().findAllRuleParams(dbSession);
assertThat(ruleParams).hasSize(1);
}
public static class XooRulesDefinition implements RulesDefinition {
+
@Override
public void define(Context context) {
- NewRepository repository = context.createRepository("xoo", "xoo").setName("Xoo Repo");
- repository.createRule("x1")
- .setName("x1 name")
- .setHtmlDescription("x1 desc")
- .setSeverity(Severity.MINOR)
- .createParam("acceptWhitespace")
- .setDefaultValue("false")
- .setType(RuleParamType.BOOLEAN)
- .setDescription("Accept whitespaces on the line");
-
- repository.createRule("x2")
- .setName("x2 name")
- .setHtmlDescription("x2 desc")
- .setSeverity(Severity.MAJOR);
- repository.done();
+ if (includeX1 || includeX2) {
+ NewRepository repository = context.createRepository("xoo", "xoo").setName("Xoo Repo");
+ if (includeX1) {
+ repository.createRule("x1")
+ .setName("x1 name")
+ .setHtmlDescription("x1 desc")
+ .setSeverity(Severity.MINOR)
+ .createParam("acceptWhitespace")
+ .setDefaultValue("false")
+ .setType(RuleParamType.BOOLEAN)
+ .setDescription("Accept whitespaces on the line");
+ }
+
+ if (includeX2) {
+ repository.createRule("x2")
+ .setName("x2 name")
+ .setHtmlDescription("x2 desc")
+ .setSeverity(Severity.MAJOR);
+ }
+ repository.done();
+ }
}
}
}
diff --git a/sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesTest.java b/sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesTest.java
index f4b55bfcbc0..88ab7080b19 100644
--- a/sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesTest.java
+++ b/sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesTest.java
@@ -36,7 +36,7 @@ import org.sonar.core.rule.RuleDto;
import org.sonar.core.rule.RuleParamDto;
import org.sonar.core.technicaldebt.db.CharacteristicDao;
import org.sonar.server.db.DbClient;
-import org.sonar.server.qualityprofile.QProfileService;
+import org.sonar.server.qualityprofile.RuleActivator;
import org.sonar.server.qualityprofile.db.ActiveRuleDao;
import org.sonar.server.rule.db.RuleDao;
@@ -53,7 +53,7 @@ public class RegisterRulesTest extends AbstractDaoTestCase {
static final Date DATE2 = DateUtils.parseDateTime("2014-02-01T12:10:03+0100");
static final Date DATE3 = DateUtils.parseDateTime("2014-03-01T12:10:03+0100");
- QProfileService profileService = mock(QProfileService.class);
+ RuleActivator ruleActivator = mock(RuleActivator.class);
System2 system;
DbClient dbClient;
DbSession dbSession;
@@ -200,7 +200,7 @@ public class RegisterRulesTest extends AbstractDaoTestCase {
private void execute(RulesDefinition... defs) {
RuleDefinitionsLoader loader = new RuleDefinitionsLoader(mock(RuleRepositories.class), defs);
- RegisterRules task = new RegisterRules(loader, profileService, dbClient, system);
+ RegisterRules task = new RegisterRules(loader, ruleActivator, dbClient, system);
task.start();
}