3 * Copyright (C) 2009-2024 SonarSource SA
4 * mailto:info AT sonarsource DOT com
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 3 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 package org.sonar.server.qualityprofile.builtin;
22 import java.util.Collection;
23 import java.util.List;
25 import java.util.Optional;
26 import javax.annotation.Nullable;
27 import org.assertj.core.groups.Tuple;
28 import org.junit.Before;
29 import org.junit.Rule;
30 import org.junit.Test;
31 import org.sonar.api.config.Configuration;
32 import org.sonar.api.impl.utils.TestSystem2;
33 import org.sonar.api.rule.RuleKey;
34 import org.sonar.api.rule.Severity;
35 import org.sonar.api.rules.RulePriority;
36 import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition;
37 import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition.NewBuiltInQualityProfile;
38 import org.sonar.api.utils.System2;
39 import org.sonar.api.utils.Version;
40 import org.sonar.core.platform.SonarQubeVersion;
41 import org.sonar.db.DbTester;
42 import org.sonar.db.qualityprofile.ActiveRuleDto;
43 import org.sonar.db.qualityprofile.ActiveRuleKey;
44 import org.sonar.db.qualityprofile.ActiveRuleParamDto;
45 import org.sonar.db.qualityprofile.OrgActiveRuleDto;
46 import org.sonar.db.qualityprofile.QProfileDto;
47 import org.sonar.db.qualityprofile.RulesProfileDto;
48 import org.sonar.db.rule.RuleDto;
49 import org.sonar.db.rule.RuleParamDto;
50 import org.sonar.server.pushapi.qualityprofile.QualityProfileChangeEventService;
51 import org.sonar.server.qualityprofile.ActiveRuleChange;
52 import org.sonar.server.qualityprofile.ActiveRuleInheritance;
53 import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
54 import org.sonar.server.tester.UserSessionRule;
55 import org.sonar.server.util.IntegerTypeValidation;
56 import org.sonar.server.util.StringTypeValidation;
57 import org.sonar.server.util.TypeValidations;
59 import static java.util.Arrays.asList;
60 import static java.util.Collections.emptyMap;
61 import static java.util.Collections.singletonList;
62 import static org.assertj.core.api.Assertions.assertThat;
63 import static org.assertj.core.groups.Tuple.tuple;
64 import static org.mockito.ArgumentMatchers.any;
65 import static org.mockito.ArgumentMatchers.eq;
66 import static org.mockito.Mockito.mock;
67 import static org.mockito.Mockito.verify;
68 import static org.mockito.Mockito.verifyNoInteractions;
69 import static org.sonar.api.rules.RulePriority.BLOCKER;
70 import static org.sonar.api.rules.RulePriority.CRITICAL;
71 import static org.sonar.api.rules.RulePriority.MAJOR;
72 import static org.sonar.api.rules.RulePriority.MINOR;
73 import static org.sonar.db.qualityprofile.QualityProfileTesting.newRuleProfileDto;
74 import static org.sonar.server.qualityprofile.ActiveRuleInheritance.INHERITED;
76 public class BuiltInQProfileUpdateImplIT {
78 private static final long NOW = 1_000;
79 private static final long PAST = NOW - 100;
82 public BuiltInQProfileRepositoryRule builtInProfileRepository = new BuiltInQProfileRepositoryRule();
84 public DbTester db = DbTester.create();
86 public UserSessionRule userSession = UserSessionRule.standalone();
87 private System2 system2 = new TestSystem2().setNow(NOW);
88 private ActiveRuleIndexer activeRuleIndexer = mock(ActiveRuleIndexer.class);
89 private TypeValidations typeValidations = new TypeValidations(asList(new StringTypeValidation(), new IntegerTypeValidation()));
90 private QualityProfileChangeEventService qualityProfileChangeEventService = mock(QualityProfileChangeEventService.class);
91 private final SonarQubeVersion sonarQubeVersion = new SonarQubeVersion(Version.create(10, 3));
92 private RuleActivator ruleActivator = new RuleActivator(system2, db.getDbClient(), typeValidations, userSession, mock(Configuration.class), sonarQubeVersion);
94 private BuiltInQProfileUpdateImpl underTest = new BuiltInQProfileUpdateImpl(db.getDbClient(), ruleActivator, activeRuleIndexer,
95 qualityProfileChangeEventService);
97 private RulesProfileDto persistedProfile;
100 public void setUp() {
101 persistedProfile = newRuleProfileDto(rp -> rp
104 .setRulesUpdatedAt(null));
105 db.getDbClient().qualityProfileDao().insert(db.getSession(), persistedProfile);
110 public void activate_new_rules() {
111 RuleDto rule1 = db.rules().insert(r -> r.setLanguage("xoo"));
112 RuleDto rule2 = db.rules().insert(r -> r.setLanguage("xoo"));
113 BuiltInQualityProfilesDefinition.Context context = new BuiltInQualityProfilesDefinition.Context();
114 NewBuiltInQualityProfile newQp = context.createBuiltInQualityProfile("Sonar way", "xoo");
115 newQp.activateRule(rule1.getRepositoryKey(), rule1.getRuleKey()).overrideSeverity(Severity.CRITICAL);
116 newQp.activateRule(rule2.getRepositoryKey(), rule2.getRuleKey()).overrideSeverity(Severity.MAJOR);
118 BuiltInQProfile builtIn = builtInProfileRepository.create(context.profile("xoo", "Sonar way"), rule1, rule2);
120 List<ActiveRuleChange> changes = underTest.update(db.getSession(), builtIn, persistedProfile);
122 List<ActiveRuleDto> activeRules = db.getDbClient().activeRuleDao().selectByRuleProfile(db.getSession(), persistedProfile);
123 assertThat(activeRules).hasSize(2);
124 assertThatRuleIsNewlyActivated(activeRules, rule1, CRITICAL);
125 assertThatRuleIsNewlyActivated(activeRules, rule2, MAJOR);
126 assertThatProfileIsMarkedAsUpdated(persistedProfile);
127 verify(qualityProfileChangeEventService).distributeRuleChangeEvent(any(), eq(changes), eq(persistedProfile.getLanguage()));
131 public void already_activated_rule_is_updated_in_case_of_differences() {
132 RuleDto rule = db.rules().insert(r -> r.setLanguage("xoo"));
133 BuiltInQualityProfilesDefinition.Context context = new BuiltInQualityProfilesDefinition.Context();
134 NewBuiltInQualityProfile newQp = context.createBuiltInQualityProfile("Sonar way", "xoo");
135 newQp.activateRule(rule.getRepositoryKey(), rule.getRuleKey()).overrideSeverity(Severity.CRITICAL);
137 BuiltInQProfile builtIn = builtInProfileRepository.create(context.profile("xoo", "Sonar way"), rule);
139 activateRuleInDb(persistedProfile, rule, BLOCKER);
141 List<ActiveRuleChange> changes = underTest.update(db.getSession(), builtIn, persistedProfile);
143 List<ActiveRuleDto> activeRules = db.getDbClient().activeRuleDao().selectByRuleProfile(db.getSession(), persistedProfile);
144 assertThat(activeRules).hasSize(1);
145 assertThatRuleIsUpdated(activeRules, rule, CRITICAL);
146 assertThatProfileIsMarkedAsUpdated(persistedProfile);
147 verify(qualityProfileChangeEventService).distributeRuleChangeEvent(any(), eq(changes), eq(persistedProfile.getLanguage()));
151 public void already_activated_rule_is_not_touched_if_no_differences() {
152 RuleDto rule = db.rules().insert(r -> r.setLanguage("xoo"));
153 BuiltInQualityProfilesDefinition.Context context = new BuiltInQualityProfilesDefinition.Context();
154 NewBuiltInQualityProfile newQp = context.createBuiltInQualityProfile("Sonar way", "xoo");
155 newQp.activateRule(rule.getRepositoryKey(), rule.getRuleKey()).overrideSeverity(Severity.CRITICAL);
157 BuiltInQProfile builtIn = builtInProfileRepository.create(context.profile("xoo", "Sonar way"), rule);
159 activateRuleInDb(persistedProfile, rule, CRITICAL);
161 underTest.update(db.getSession(), builtIn, persistedProfile);
163 List<ActiveRuleDto> activeRules = db.getDbClient().activeRuleDao().selectByRuleProfile(db.getSession(), persistedProfile);
164 assertThat(activeRules).hasSize(1);
165 assertThatRuleIsUntouched(activeRules, rule, CRITICAL);
166 assertThatProfileIsNotMarkedAsUpdated(persistedProfile);
167 verifyNoInteractions(qualityProfileChangeEventService);
171 public void deactivate_rule_that_is_not_in_built_in_definition_anymore() {
172 RuleDto rule1 = db.rules().insert(r -> r.setLanguage("xoo"));
173 RuleDto rule2 = db.rules().insert(r -> r.setLanguage("xoo"));
174 BuiltInQualityProfilesDefinition.Context context = new BuiltInQualityProfilesDefinition.Context();
175 NewBuiltInQualityProfile newQp = context.createBuiltInQualityProfile("Sonar way", "xoo");
176 newQp.activateRule(rule2.getRepositoryKey(), rule2.getRuleKey()).overrideSeverity(Severity.MAJOR);
178 BuiltInQProfile builtIn = builtInProfileRepository.create(context.profile("xoo", "Sonar way"), rule1, rule2);
180 // built-in definition contains only rule2
181 // so rule1 must be deactivated
182 activateRuleInDb(persistedProfile, rule1, CRITICAL);
184 List<ActiveRuleChange> changes = underTest.update(db.getSession(), builtIn, persistedProfile);
186 List<ActiveRuleDto> activeRules = db.getDbClient().activeRuleDao().selectByRuleProfile(db.getSession(), persistedProfile);
187 assertThat(activeRules).hasSize(1);
188 assertThatRuleIsDeactivated(activeRules, rule1);
189 assertThatProfileIsMarkedAsUpdated(persistedProfile);
190 verify(qualityProfileChangeEventService).distributeRuleChangeEvent(any(), eq(changes), eq(persistedProfile.getLanguage()));
194 public void activate_deactivate_and_update_three_rules_at_the_same_time() {
195 RuleDto rule1 = db.rules().insert(r -> r.setLanguage("xoo"));
196 RuleDto rule2 = db.rules().insert(r -> r.setLanguage("xoo"));
197 RuleDto rule3 = db.rules().insert(r -> r.setLanguage("xoo"));
199 BuiltInQualityProfilesDefinition.Context context = new BuiltInQualityProfilesDefinition.Context();
200 NewBuiltInQualityProfile newQp = context.createBuiltInQualityProfile("Sonar way", "xoo");
201 newQp.activateRule(rule1.getRepositoryKey(), rule1.getRuleKey()).overrideSeverity(Severity.CRITICAL);
202 newQp.activateRule(rule2.getRepositoryKey(), rule2.getRuleKey()).overrideSeverity(Severity.MAJOR);
204 BuiltInQProfile builtIn = builtInProfileRepository.create(context.profile("xoo", "Sonar way"), rule1, rule2);
206 // rule1 must be updated (blocker to critical)
207 // rule2 must be activated
208 // rule3 must be deactivated
209 activateRuleInDb(persistedProfile, rule1, BLOCKER);
210 activateRuleInDb(persistedProfile, rule3, BLOCKER);
212 List<ActiveRuleChange> changes = underTest.update(db.getSession(), builtIn, persistedProfile);
214 List<ActiveRuleDto> activeRules = db.getDbClient().activeRuleDao().selectByRuleProfile(db.getSession(), persistedProfile);
215 assertThat(activeRules).hasSize(2);
216 assertThatRuleIsUpdated(activeRules, rule1, CRITICAL);
217 assertThatRuleIsNewlyActivated(activeRules, rule2, MAJOR);
218 assertThatRuleIsDeactivated(activeRules, rule3);
219 assertThatProfileIsMarkedAsUpdated(persistedProfile);
220 verify(qualityProfileChangeEventService).distributeRuleChangeEvent(any(), eq(changes), eq(persistedProfile.getLanguage()));
225 public void activate_rule_on_built_in_profile_resets_severity_to_default_if_not_overridden() {
226 RuleDto rule = db.rules().insert(r -> r.setSeverity(Severity.MAJOR).setLanguage("xoo"));
228 BuiltInQualityProfilesDefinition.Context context = new BuiltInQualityProfilesDefinition.Context();
229 NewBuiltInQualityProfile newQp = context.createBuiltInQualityProfile("Sonar way", "xoo");
230 newQp.activateRule(rule.getRepositoryKey(), rule.getRuleKey());
232 BuiltInQProfile builtIn = builtInProfileRepository.create(context.profile("xoo", "Sonar way"), rule);
233 underTest.update(db.getSession(), builtIn, persistedProfile);
235 List<ActiveRuleDto> activeRules = db.getDbClient().activeRuleDao().selectByRuleProfile(db.getSession(), persistedProfile);
236 assertThatRuleIsNewlyActivated(activeRules, rule, MAJOR);
238 // emulate an upgrade of analyzer that changes the default severity of the rule
239 rule.setSeverity(Severity.MINOR);
240 db.rules().update(rule);
242 List<ActiveRuleChange> changes = underTest.update(db.getSession(), builtIn, persistedProfile);
243 activeRules = db.getDbClient().activeRuleDao().selectByRuleProfile(db.getSession(), persistedProfile);
244 assertThatRuleIsNewlyActivated(activeRules, rule, MINOR);
245 verify(qualityProfileChangeEventService).distributeRuleChangeEvent(any(), eq(changes), eq(persistedProfile.getLanguage()));
249 public void activate_rule_on_built_in_profile_resets_params_to_default_if_not_overridden() {
250 RuleDto rule = db.rules().insert(r -> r.setLanguage("xoo"));
251 RuleParamDto ruleParam = db.rules().insertRuleParam(rule, p -> p.setName("min").setDefaultValue("10"));
253 BuiltInQualityProfilesDefinition.Context context = new BuiltInQualityProfilesDefinition.Context();
254 NewBuiltInQualityProfile newQp = context.createBuiltInQualityProfile("Sonar way", rule.getLanguage());
255 newQp.activateRule(rule.getRepositoryKey(), rule.getRuleKey());
257 BuiltInQProfile builtIn = builtInProfileRepository.create(context.profile(newQp.language(), newQp.name()), rule);
258 List<ActiveRuleChange> changes = underTest.update(db.getSession(), builtIn, persistedProfile);
260 List<ActiveRuleDto> activeRules = db.getDbClient().activeRuleDao().selectByRuleProfile(db.getSession(), persistedProfile);
261 assertThat(activeRules).hasSize(1);
262 assertThatRuleHasParams(db, activeRules.get(0), tuple("min", "10"));
263 verify(qualityProfileChangeEventService).distributeRuleChangeEvent(any(), eq(changes), eq(persistedProfile.getLanguage()));
265 // emulate an upgrade of analyzer that changes the default value of parameter min
266 ruleParam.setDefaultValue("20");
267 db.getDbClient().ruleDao().updateRuleParam(db.getSession(), rule, ruleParam);
269 changes = underTest.update(db.getSession(), builtIn, persistedProfile);
270 activeRules = db.getDbClient().activeRuleDao().selectByRuleProfile(db.getSession(), persistedProfile);
271 assertThat(activeRules).hasSize(1);
272 assertThatRuleHasParams(db, activeRules.get(0), tuple("min", "20"));
273 verify(qualityProfileChangeEventService).distributeRuleChangeEvent(any(), eq(changes), eq(persistedProfile.getLanguage()));
277 public void propagate_activation_to_descendant_profiles() {
278 RuleDto rule = db.rules().insert(r -> r.setLanguage("xoo"));
280 QProfileDto profile = db.qualityProfiles().insert(p -> p.setLanguage(rule.getLanguage()).setIsBuiltIn(true));
281 QProfileDto childProfile = createChildProfile(profile);
282 QProfileDto grandchildProfile = createChildProfile(childProfile);
284 BuiltInQualityProfilesDefinition.Context context = new BuiltInQualityProfilesDefinition.Context();
285 NewBuiltInQualityProfile newQp = context.createBuiltInQualityProfile(profile.getName(), profile.getLanguage());
286 newQp.activateRule(rule.getRepositoryKey(), rule.getRuleKey());
288 BuiltInQProfile builtIn = builtInProfileRepository.create(context.profile(profile.getLanguage(), profile.getName()), rule);
289 List<ActiveRuleChange> changes = underTest.update(db.getSession(), builtIn, RulesProfileDto.from(profile));
291 assertThat(changes).hasSize(3);
292 assertThatRuleIsActivated(profile, rule, changes, rule.getSeverityString(), null, emptyMap());
293 assertThatRuleIsActivated(childProfile, rule, changes, rule.getSeverityString(), INHERITED, emptyMap());
294 assertThatRuleIsActivated(grandchildProfile, rule, changes, rule.getSeverityString(), INHERITED, emptyMap());
295 verify(qualityProfileChangeEventService).distributeRuleChangeEvent(any(), eq(changes), eq(persistedProfile.getLanguage()));
300 public void propagate_rule_update_to_descendant_active_rule() {
301 RuleDto rule = db.rules().insert(r -> r.setLanguage("xoo").setSeverity(Severity.BLOCKER));
303 QProfileDto parentProfile = db.qualityProfiles().insert(p -> p.setLanguage(rule.getLanguage()).setIsBuiltIn(true));
304 activateRuleInDb(RulesProfileDto.from(parentProfile), rule, RulePriority.valueOf(Severity.MINOR), null);
306 QProfileDto childProfile = createChildProfile(parentProfile);
307 activateRuleInDb(RulesProfileDto.from(childProfile), rule, RulePriority.valueOf(Severity.MINOR), INHERITED);
309 BuiltInQualityProfilesDefinition.Context context = new BuiltInQualityProfilesDefinition.Context();
310 NewBuiltInQualityProfile newQp = context.createBuiltInQualityProfile(parentProfile.getName(), parentProfile.getLanguage());
311 newQp.activateRule(rule.getRepositoryKey(), rule.getRuleKey());
313 BuiltInQProfile builtIn = builtInProfileRepository.create(context.profile(parentProfile.getLanguage(), parentProfile.getName()), rule);
314 List<ActiveRuleChange> changes = underTest.update(db.getSession(), builtIn, RulesProfileDto.from(parentProfile));
316 assertThat(changes).hasSize(2);
318 List<ActiveRuleDto> parentActiveRules = db.getDbClient().activeRuleDao().selectByRuleProfile(db.getSession(), RulesProfileDto.from(parentProfile));
319 assertThatRuleIsUpdated(parentActiveRules, rule, RulePriority.BLOCKER, null);
321 List<ActiveRuleDto> childActiveRules = db.getDbClient().activeRuleDao().selectByRuleProfile(db.getSession(), RulesProfileDto.from(childProfile));
322 assertThatRuleIsUpdated(childActiveRules, rule, RulePriority.BLOCKER, INHERITED);
323 verify(qualityProfileChangeEventService).distributeRuleChangeEvent(any(), eq(changes), eq(persistedProfile.getLanguage()));
327 public void propagate_rule_param_update_to_descendant_active_rule_params() {
328 RuleDto rule = db.rules().insert(r -> r.setLanguage("xoo").setSeverity(Severity.BLOCKER));
329 RuleParamDto ruleParam = db.rules().insertRuleParam(rule, p -> p.setName("min").setDefaultValue("10"));
331 QProfileDto parentProfile = db.qualityProfiles().insert(p -> p.setLanguage(rule.getLanguage()).setIsBuiltIn(true));
332 ActiveRuleDto parentActiveRuleDto = activateRuleInDb(RulesProfileDto.from(parentProfile), rule,
333 RulePriority.valueOf(Severity.MINOR), null);
334 activateRuleParamInDb(parentActiveRuleDto, ruleParam, "20");
336 QProfileDto childProfile = createChildProfile(parentProfile);
337 ActiveRuleDto childActiveRuleDto = activateRuleInDb(RulesProfileDto.from(childProfile), rule,
338 RulePriority.valueOf(Severity.MINOR), INHERITED);
339 activateRuleParamInDb(childActiveRuleDto, ruleParam, "20");
341 BuiltInQualityProfilesDefinition.Context context = new BuiltInQualityProfilesDefinition.Context();
342 NewBuiltInQualityProfile newQp = context.createBuiltInQualityProfile(parentProfile.getName(), parentProfile.getLanguage());
343 newQp.activateRule(rule.getRepositoryKey(), rule.getRuleKey());
345 BuiltInQProfile builtIn = builtInProfileRepository.create(context.profile(parentProfile.getLanguage(), parentProfile.getName()), rule);
346 List<ActiveRuleChange> changes = underTest.update(db.getSession(), builtIn, RulesProfileDto.from(parentProfile));
348 assertThat(changes).hasSize(2);
350 assertThatRuleHasParams(db, parentActiveRuleDto, tuple("min", "10"));
351 assertThatRuleHasParams(db, childActiveRuleDto, tuple("min", "10"));
352 verify(qualityProfileChangeEventService).distributeRuleChangeEvent(any(), eq(changes), eq(persistedProfile.getLanguage()));
356 public void propagate_deactivation_to_descendant_profiles() {
357 RuleDto rule = db.rules().insert(r -> r.setLanguage("xoo"));
359 QProfileDto profile = db.qualityProfiles().insert(p -> p.setLanguage(rule.getLanguage()).setIsBuiltIn(true));
360 QProfileDto childProfile = createChildProfile(profile);
361 QProfileDto grandChildProfile = createChildProfile(childProfile);
363 BuiltInQualityProfilesDefinition.Context context = new BuiltInQualityProfilesDefinition.Context();
364 NewBuiltInQualityProfile newQp = context.createBuiltInQualityProfile(profile.getName(), profile.getLanguage());
365 newQp.activateRule(rule.getRepositoryKey(), rule.getRuleKey());
368 // first run to activate the rule
369 BuiltInQProfile builtIn = builtInProfileRepository.create(context.profile(profile.getLanguage(), profile.getName()), rule);
370 List<ActiveRuleChange> changes = underTest.update(db.getSession(), builtIn, RulesProfileDto.from(profile));
371 assertThat(changes).hasSize(3).extracting(ActiveRuleChange::getType).containsOnly(ActiveRuleChange.Type.ACTIVATED);
372 verify(qualityProfileChangeEventService).distributeRuleChangeEvent(any(), eq(changes), eq(persistedProfile.getLanguage()));
374 // second run to deactivate the rule
375 context = new BuiltInQualityProfilesDefinition.Context();
376 NewBuiltInQualityProfile updatedQp = context.createBuiltInQualityProfile(profile.getName(), profile.getLanguage());
378 builtIn = builtInProfileRepository.create(context.profile(profile.getLanguage(), profile.getName()), rule);
379 changes = underTest.update(db.getSession(), builtIn, RulesProfileDto.from(profile));
380 assertThat(changes).hasSize(3).extracting(ActiveRuleChange::getType).containsOnly(ActiveRuleChange.Type.DEACTIVATED);
381 verify(qualityProfileChangeEventService).distributeRuleChangeEvent(any(), eq(changes), eq(persistedProfile.getLanguage()));
383 assertThatRuleIsDeactivated(profile, rule);
384 assertThatRuleIsDeactivated(childProfile, rule);
385 assertThatRuleIsDeactivated(grandChildProfile, rule);
388 private QProfileDto createChildProfile(QProfileDto parent) {
389 return db.qualityProfiles().insert(p -> p
390 .setLanguage(parent.getLanguage())
391 .setParentKee(parent.getKee())
392 .setName("Child of " + parent.getName()))
393 .setIsBuiltIn(false);
396 private void assertThatRuleIsActivated(QProfileDto profile, RuleDto rule, @Nullable List<ActiveRuleChange> changes,
397 String expectedSeverity, @Nullable ActiveRuleInheritance expectedInheritance, Map<String, String> expectedParams) {
398 OrgActiveRuleDto activeRule = db.getDbClient().activeRuleDao().selectByProfile(db.getSession(), profile)
400 .filter(ar -> ar.getRuleKey().equals(rule.getKey()))
402 .orElseThrow(IllegalStateException::new);
404 assertThat(activeRule.getSeverityString()).isEqualTo(expectedSeverity);
405 assertThat(activeRule.getInheritance()).isEqualTo(expectedInheritance != null ? expectedInheritance.name() : null);
407 List<ActiveRuleParamDto> params = db.getDbClient().activeRuleDao().selectParamsByActiveRuleUuid(db.getSession(), activeRule.getUuid());
408 assertThat(params).hasSize(expectedParams.size());
410 if (changes != null) {
411 ActiveRuleChange change = changes.stream()
412 .filter(c -> c.getActiveRule().getUuid().equals(activeRule.getUuid()))
413 .findFirst().orElseThrow(IllegalStateException::new);
414 assertThat(change.getInheritance()).isEqualTo(expectedInheritance);
415 assertThat(change.getSeverity()).isEqualTo(expectedSeverity);
416 assertThat(change.getType()).isEqualTo(ActiveRuleChange.Type.ACTIVATED);
420 private static void assertThatRuleHasParams(DbTester db, ActiveRuleDto activeRule, Tuple... expectedParams) {
421 assertThat(db.getDbClient().activeRuleDao().selectParamsByActiveRuleUuid(db.getSession(), activeRule.getUuid()))
422 .extracting(ActiveRuleParamDto::getKey, ActiveRuleParamDto::getValue)
423 .containsExactlyInAnyOrder(expectedParams);
426 private static void assertThatRuleIsNewlyActivated(List<ActiveRuleDto> activeRules, RuleDto rule, RulePriority severity) {
427 ActiveRuleDto activeRule = findRule(activeRules, rule).get();
429 assertThat(activeRule.getInheritance()).isNull();
430 assertThat(activeRule.getSeverityString()).isEqualTo(severity.name());
431 assertThat(activeRule.getCreatedAt()).isEqualTo(NOW);
432 assertThat(activeRule.getUpdatedAt()).isEqualTo(NOW);
435 private static void assertThatRuleIsUpdated(List<ActiveRuleDto> activeRules, RuleDto rule, RulePriority severity, @Nullable ActiveRuleInheritance expectedInheritance) {
436 ActiveRuleDto activeRule = findRule(activeRules, rule).get();
438 if (expectedInheritance != null) {
439 assertThat(activeRule.getInheritance()).isEqualTo(expectedInheritance.name());
441 assertThat(activeRule.getInheritance()).isNull();
443 assertThat(activeRule.getSeverityString()).isEqualTo(severity.name());
444 assertThat(activeRule.getCreatedAt()).isEqualTo(PAST);
445 assertThat(activeRule.getUpdatedAt()).isEqualTo(NOW);
448 private static void assertThatRuleIsUpdated(List<ActiveRuleDto> activeRules, RuleDto rule, RulePriority severity) {
449 assertThatRuleIsUpdated(activeRules, rule, severity, null);
452 private static void assertThatRuleIsUpdated(ActiveRuleDto activeRules, RuleDto rule, RulePriority severity, @Nullable ActiveRuleInheritance expectedInheritance) {
453 assertThatRuleIsUpdated(singletonList(activeRules), rule, severity, expectedInheritance);
456 private static void assertThatRuleIsUntouched(List<ActiveRuleDto> activeRules, RuleDto rule, RulePriority severity) {
457 ActiveRuleDto activeRule = findRule(activeRules, rule).get();
459 assertThat(activeRule.getInheritance()).isNull();
460 assertThat(activeRule.getSeverityString()).isEqualTo(severity.name());
461 assertThat(activeRule.getCreatedAt()).isEqualTo(PAST);
462 assertThat(activeRule.getUpdatedAt()).isEqualTo(PAST);
465 private void assertThatRuleIsDeactivated(QProfileDto profile, RuleDto rule) {
466 Collection<ActiveRuleDto> activeRules = db.getDbClient().activeRuleDao().selectByRulesAndRuleProfileUuids(
467 db.getSession(), singletonList(rule.getUuid()), singletonList(profile.getRulesProfileUuid()));
468 assertThat(activeRules).isEmpty();
471 private static void assertThatRuleIsDeactivated(List<ActiveRuleDto> activeRules, RuleDto rule) {
472 assertThat(findRule(activeRules, rule)).isEmpty();
475 private void assertThatProfileIsMarkedAsUpdated(RulesProfileDto dto) {
476 RulesProfileDto reloaded = db.getDbClient().qualityProfileDao().selectBuiltInRuleProfiles(db.getSession())
478 .filter(p -> p.getUuid().equals(dto.getUuid()))
481 assertThat(reloaded.getRulesUpdatedAt()).isNotEmpty();
484 private void assertThatProfileIsNotMarkedAsUpdated(RulesProfileDto dto) {
485 RulesProfileDto reloaded = db.getDbClient().qualityProfileDao().selectBuiltInRuleProfiles(db.getSession())
487 .filter(p -> p.getUuid().equals(dto.getUuid()))
490 assertThat(reloaded.getRulesUpdatedAt()).isNull();
493 private static Optional<ActiveRuleDto> findRule(List<ActiveRuleDto> activeRules, RuleDto rule) {
494 return activeRules.stream()
495 .filter(ar -> ar.getRuleKey().equals(rule.getKey()))
499 private ActiveRuleDto activateRuleInDb(RulesProfileDto profile, RuleDto rule, RulePriority severity) {
500 return activateRuleInDb(profile, rule, severity, null);
503 private ActiveRuleDto activateRuleInDb(RulesProfileDto ruleProfile, RuleDto rule, RulePriority severity, @Nullable ActiveRuleInheritance inheritance) {
504 ActiveRuleDto dto = new ActiveRuleDto()
505 .setKey(ActiveRuleKey.of(ruleProfile, RuleKey.of(rule.getRepositoryKey(), rule.getRuleKey())))
506 .setProfileUuid(ruleProfile.getUuid())
507 .setSeverity(severity.name())
508 .setRuleUuid(rule.getUuid())
509 .setInheritance(inheritance != null ? inheritance.name() : null)
512 db.getDbClient().activeRuleDao().insert(db.getSession(), dto);
517 private void activateRuleParamInDb(ActiveRuleDto activeRuleDto, RuleParamDto ruleParamDto, String value) {
518 ActiveRuleParamDto dto = new ActiveRuleParamDto()
519 .setActiveRuleUuid(activeRuleDto.getUuid())
520 .setRulesParameterUuid(ruleParamDto.getUuid())
521 .setKey(ruleParamDto.getName())
523 db.getDbClient().activeRuleDao().insertParam(db.getSession(), activeRuleDto, dto);