]> source.dussan.org Git - sonarqube.git/blob
e7184d2f52b0cf1bb5d7d94c9e151e2ed55a54bc
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2024 SonarSource SA
4  * mailto:info AT sonarsource DOT com
5  *
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.
10  *
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.
15  *
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.
19  */
20 package org.sonar.server.qualityprofile.builtin;
21
22 import java.util.List;
23 import javax.annotation.Nullable;
24 import org.junit.jupiter.api.Test;
25 import org.junit.jupiter.api.extension.RegisterExtension;
26 import org.sonar.api.config.Configuration;
27 import org.sonar.api.impl.utils.TestSystem2;
28 import org.sonar.api.rule.RuleKey;
29 import org.sonar.api.rule.Severity;
30 import org.sonar.api.rules.RulePriority;
31 import org.sonar.api.utils.System2;
32 import org.sonar.api.utils.Version;
33 import org.sonar.core.platform.SonarQubeVersion;
34 import org.sonar.db.DbSession;
35 import org.sonar.db.DbTester;
36 import org.sonar.db.qualityprofile.ActiveRuleDto;
37 import org.sonar.db.qualityprofile.ActiveRuleKey;
38 import org.sonar.db.qualityprofile.ActiveRuleParamDto;
39 import org.sonar.db.qualityprofile.QProfileDto;
40 import org.sonar.db.qualityprofile.RulesProfileDto;
41 import org.sonar.db.rule.RuleDto;
42 import org.sonar.db.rule.RuleParamDto;
43 import org.sonar.server.exceptions.BadRequestException;
44 import org.sonar.server.pushapi.qualityprofile.QualityProfileChangeEventService;
45 import org.sonar.server.qualityprofile.ActiveRuleChange;
46 import org.sonar.server.qualityprofile.ActiveRuleInheritance;
47 import org.sonar.server.qualityprofile.RuleActivation;
48 import org.sonar.server.qualityprofile.builtin.DescendantProfilesSupplier.Result;
49 import org.sonar.server.tester.UserSessionRule;
50 import org.sonar.server.util.IntegerTypeValidation;
51 import org.sonar.server.util.StringTypeValidation;
52 import org.sonar.server.util.TypeValidations;
53
54 import static java.lang.Boolean.TRUE;
55 import static java.util.Arrays.asList;
56 import static java.util.Collections.emptyList;
57 import static java.util.Collections.singletonList;
58 import static java.util.Map.of;
59 import static org.assertj.core.api.Assertions.assertThat;
60 import static org.junit.Assert.assertThrows;
61 import static org.mockito.Mockito.mock;
62 import static org.sonar.server.qualityprofile.ActiveRuleInheritance.INHERITED;
63 import static org.sonar.server.qualityprofile.ActiveRuleInheritance.OVERRIDES;
64
65 /**
66  * Class org.sonar.server.qualityprofile.builtin.RuleActivator is mostly covered in
67  * org.sonar.server.qualityprofile.builtin.BuiltInQProfileUpdateImplTest
68  */
69 class RuleActivatorIT {
70   @RegisterExtension
71   public final DbTester db = DbTester.create();
72
73   @RegisterExtension
74   public final UserSessionRule userSession = UserSessionRule.standalone();
75
76   private static final long NOW = 1_000;
77   private static final long PAST = NOW - 100;
78   private final System2 system2 = new TestSystem2().setNow(NOW);
79   private final TypeValidations typeValidations = new TypeValidations(asList(new StringTypeValidation(), new IntegerTypeValidation()));
80
81   private final QualityProfileChangeEventService qualityProfileChangeEventService = mock(QualityProfileChangeEventService.class);
82   private final SonarQubeVersion sonarQubeVersion = new SonarQubeVersion(Version.create(10, 3));
83   private final RuleActivator underTest = new RuleActivator(system2, db.getDbClient(), typeValidations, userSession,
84     mock(Configuration.class), sonarQubeVersion);
85
86   @Test
87   void reset_overridden_active_rule() {
88     RuleDto rule = db.rules().insert(r -> r.setLanguage("xoo").setSeverity(Severity.BLOCKER));
89     RuleParamDto ruleParam = db.rules().insertRuleParam(rule, p -> p.setName("min").setDefaultValue("10"));
90
91     QProfileDto parentProfile = db.qualityProfiles().insert(p -> p.setLanguage(rule.getLanguage()).setIsBuiltIn(true));
92     ActiveRuleDto parentActiveRuleDto = activateRuleInDb(RulesProfileDto.from(parentProfile), rule,
93       RulePriority.valueOf(Severity.BLOCKER), false, null);
94     ActiveRuleParamDto parentActiveRuleParam = activateRuleParamInDb(parentActiveRuleDto, ruleParam, "10");
95
96     QProfileDto childProfile = createChildProfile(parentProfile);
97     ActiveRuleDto childActiveRuleDto = activateRuleInDb(RulesProfileDto.from(childProfile), rule,
98       RulePriority.valueOf(Severity.MINOR), true, OVERRIDES);
99     ActiveRuleParamDto childActiveRuleParam = activateRuleParamInDb(childActiveRuleDto, ruleParam, "15");
100
101     DbSession session = db.getSession();
102     RuleActivation resetRequest = RuleActivation.createReset(rule.getUuid());
103     RuleActivationContext context = new RuleActivationContext.Builder()
104       .setProfiles(asList(parentProfile, childProfile))
105       .setBaseProfile(RulesProfileDto.from(childProfile))
106       .setDate(NOW)
107       .setDescendantProfilesSupplier((profiles, ruleUuids) -> new Result(emptyList(), emptyList(), emptyList()))
108       .setRules(singletonList(rule))
109       .setRuleParams(singletonList(ruleParam))
110       .setActiveRules(asList(parentActiveRuleDto, childActiveRuleDto))
111       .setActiveRuleParams(asList(parentActiveRuleParam, childActiveRuleParam))
112       .build();
113
114     List<ActiveRuleChange> result = underTest.activate(session, resetRequest, context);
115
116     assertThat(result).hasSize(1);
117     ActiveRuleChange activeRuleResult = result.get(0);
118     assertThat(activeRuleResult.getParameters()).containsEntry("min", "10");
119     assertThat(activeRuleResult.getSeverity()).isEqualTo(Severity.BLOCKER);
120     assertThat(activeRuleResult.isPrioritizedRule()).isFalse();
121     assertThat(activeRuleResult.getInheritance()).isEqualTo(ActiveRuleInheritance.INHERITED);
122   }
123
124   @Test
125   void request_new_severity_and_prioritized_rule_and_param_for_child_rule() {
126     RuleDto rule = db.rules().insert(r -> r.setLanguage("xoo").setSeverity(Severity.BLOCKER));
127     RuleParamDto ruleParam = db.rules().insertRuleParam(rule, p -> p.setName("min").setDefaultValue("10"));
128
129     QProfileDto parentProfile = db.qualityProfiles().insert(p -> p.setLanguage(rule.getLanguage()).setIsBuiltIn(true));
130     ActiveRuleDto parentActiveRuleDto = activateRuleInDb(RulesProfileDto.from(parentProfile), rule,
131       RulePriority.valueOf(Severity.BLOCKER), null, null);
132     ActiveRuleParamDto parentActiveRuleParam = activateRuleParamInDb(parentActiveRuleDto, ruleParam, "10");
133
134     QProfileDto childProfile = createChildProfile(parentProfile);
135     ActiveRuleDto childActiveRuleDto = activateRuleInDb(RulesProfileDto.from(childProfile), rule,
136       RulePriority.valueOf(Severity.BLOCKER), null, INHERITED);
137     ActiveRuleParamDto childActiveRuleParam = activateRuleParamInDb(childActiveRuleDto, ruleParam, "10");
138
139     DbSession session = db.getSession();
140     RuleActivation resetRequest = RuleActivation.create(rule.getUuid(), Severity.MINOR, true, of("min", "15"));
141     RuleActivationContext context = new RuleActivationContext.Builder()
142       .setProfiles(asList(parentProfile, childProfile))
143       .setBaseProfile(RulesProfileDto.from(childProfile))
144       .setDate(NOW)
145       .setDescendantProfilesSupplier((profiles, ruleUuids) -> new Result(emptyList(), emptyList(), emptyList()))
146       .setRules(singletonList(rule))
147       .setRuleParams(singletonList(ruleParam))
148       .setActiveRules(asList(parentActiveRuleDto, childActiveRuleDto))
149       .setActiveRuleParams(asList(parentActiveRuleParam, childActiveRuleParam))
150       .build();
151
152     List<ActiveRuleChange> result = underTest.activate(session, resetRequest, context);
153
154     assertThat(result).hasSize(1);
155     ActiveRuleChange activeRuleResult = result.get(0);
156     assertThat(activeRuleResult.getParameters()).containsEntry("min", "15");
157     assertThat(activeRuleResult.getSeverity()).isEqualTo(Severity.MINOR);
158     assertThat(activeRuleResult.isPrioritizedRule()).isTrue();
159     assertThat(activeRuleResult.getInheritance()).isEqualTo(OVERRIDES);
160   }
161
162   @Test
163   void set_severity_and_param_for_child_rule_when_activating() {
164     RuleDto rule = db.rules().insert(r -> r.setLanguage("xoo").setSeverity(Severity.BLOCKER));
165     RuleParamDto ruleParam = db.rules().insertRuleParam(rule, p -> p.setName("min").setDefaultValue("10"));
166
167     QProfileDto parentProfile = db.qualityProfiles().insert(p -> p.setLanguage(rule.getLanguage()).setIsBuiltIn(true));
168
169     QProfileDto childProfile = createChildProfile(parentProfile);
170
171     DbSession session = db.getSession();
172     RuleActivation resetRequest = RuleActivation.create(rule.getUuid());
173     RuleActivationContext context = new RuleActivationContext.Builder()
174       .setProfiles(asList(parentProfile, childProfile))
175       .setBaseProfile(RulesProfileDto.from(childProfile))
176       .setDate(NOW)
177       .setDescendantProfilesSupplier((profiles, ruleUuids) -> new Result(emptyList(), emptyList(), emptyList()))
178       .setRules(singletonList(rule))
179       .setRuleParams(singletonList(ruleParam))
180       .setActiveRules(emptyList())
181       .setActiveRuleParams(emptyList())
182       .build();
183
184     List<ActiveRuleChange> result = underTest.activate(session, resetRequest, context);
185
186     assertThat(result).hasSize(1);
187     assertThat(result.get(0).getParameters()).containsEntry("min", "10");
188     assertThat(result.get(0).getSeverity()).isEqualTo(Severity.BLOCKER);
189     assertThat(result.get(0).getInheritance()).isNull();
190   }
191
192   @Test
193   void fail_if_rule_language_doesnt_match_qp() {
194     RuleDto rule = db.rules().insert(r -> r.setLanguage("xoo")
195       .setRepositoryKey("repo")
196       .setRuleKey("rule")
197       .setSeverity(Severity.BLOCKER));
198     QProfileDto qp = db.qualityProfiles().insert(p -> p.setLanguage("xoo2").setKee("qp").setIsBuiltIn(true));
199
200     DbSession session = db.getSession();
201     RuleActivation resetRequest = RuleActivation.create(rule.getUuid());
202     RuleActivationContext context = new RuleActivationContext.Builder()
203       .setProfiles(singletonList(qp))
204       .setBaseProfile(RulesProfileDto.from(qp))
205       .setDate(NOW)
206       .setDescendantProfilesSupplier((profiles, ruleUuids) -> new Result(emptyList(), emptyList(), emptyList()))
207       .setRules(singletonList(rule))
208       .setRuleParams(emptyList())
209       .setActiveRules(emptyList())
210       .setActiveRuleParams(emptyList())
211       .build();
212
213
214     assertThrows("xoo rule repo:rule cannot be activated on xoo2 profile qp", BadRequestException.class,
215       () -> underTest.activate(session, resetRequest, context));
216   }
217
218
219   private ActiveRuleDto activateRuleInDb(RulesProfileDto ruleProfile, RuleDto rule, RulePriority severity,
220     @Nullable Boolean prioritizedRule, @Nullable ActiveRuleInheritance inheritance) {
221     ActiveRuleDto dto = new ActiveRuleDto()
222       .setKey(ActiveRuleKey.of(ruleProfile, RuleKey.of(rule.getRepositoryKey(), rule.getRuleKey())))
223       .setProfileUuid(ruleProfile.getUuid())
224       .setSeverity(severity.name())
225       .setPrioritizedRule(TRUE.equals(prioritizedRule))
226       .setRuleUuid(rule.getUuid())
227       .setInheritance(inheritance != null ? inheritance.name() : null)
228       .setCreatedAt(PAST)
229       .setUpdatedAt(PAST);
230     db.getDbClient().activeRuleDao().insert(db.getSession(), dto);
231     db.commit();
232     return dto;
233   }
234
235   private ActiveRuleParamDto activateRuleParamInDb(ActiveRuleDto activeRuleDto, RuleParamDto ruleParamDto, String value) {
236     ActiveRuleParamDto dto = new ActiveRuleParamDto()
237       .setActiveRuleUuid(activeRuleDto.getUuid())
238       .setRulesParameterUuid(ruleParamDto.getUuid())
239       .setKey(ruleParamDto.getName())
240       .setValue(value);
241     db.getDbClient().activeRuleDao().insertParam(db.getSession(), activeRuleDto, dto);
242     db.commit();
243     return dto;
244   }
245
246   private QProfileDto createChildProfile(QProfileDto parent) {
247     return db.qualityProfiles().insert(p -> p
248         .setLanguage(parent.getLanguage())
249         .setParentKee(parent.getKee())
250         .setName("Child of " + parent.getName()))
251       .setIsBuiltIn(false);
252   }
253 }