3 * Copyright (C) 2009-2020 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.ws;
22 import com.google.common.collect.ImmutableSet;
23 import java.util.Collections;
24 import java.util.Optional;
25 import org.junit.Rule;
26 import org.junit.Test;
27 import org.sonar.api.rule.RuleKey;
28 import org.sonar.api.rule.RuleStatus;
29 import org.sonar.api.rule.Severity;
30 import org.sonar.api.server.ws.WebService.Param;
31 import org.sonar.api.utils.System2;
32 import org.sonar.db.DbClient;
33 import org.sonar.db.DbSession;
34 import org.sonar.db.DbTester;
35 import org.sonar.db.qualityprofile.ActiveRuleDto;
36 import org.sonar.db.qualityprofile.ActiveRuleKey;
37 import org.sonar.db.qualityprofile.QProfileDto;
38 import org.sonar.db.rule.RuleDefinitionDto;
39 import org.sonar.db.rule.RuleTesting;
40 import org.sonar.server.es.EsTester;
41 import org.sonar.server.es.SearchOptions;
42 import org.sonar.server.exceptions.BadRequestException;
43 import org.sonar.server.qualityprofile.QProfileName;
44 import org.sonar.server.qualityprofile.QProfileRules;
45 import org.sonar.server.qualityprofile.QProfileRulesImpl;
46 import org.sonar.server.qualityprofile.QProfileTesting;
47 import org.sonar.server.qualityprofile.RuleActivator;
48 import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
49 import org.sonar.server.rule.index.RuleIndex;
50 import org.sonar.server.rule.index.RuleIndexer;
51 import org.sonar.server.rule.index.RuleQuery;
52 import org.sonar.server.rule.ws.RuleQueryFactory;
53 import org.sonar.server.tester.UserSessionRule;
54 import org.sonar.server.util.TypeValidations;
55 import org.sonar.server.ws.WsActionTester;
57 import static java.util.Collections.emptyList;
58 import static org.assertj.core.api.Assertions.assertThat;
59 import static org.junit.Assert.fail;
60 import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_LANGUAGES;
61 import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_QPROFILE;
62 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_KEY;
63 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_RESET;
64 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_RULE;
65 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_SEVERITY;
66 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_TARGET_KEY;
67 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_TARGET_SEVERITY;
69 public class QProfilesWsMediumTest {
72 public UserSessionRule userSessionRule = UserSessionRule.standalone()
75 public EsTester es = EsTester.create();
77 public DbTester dbTester = DbTester.create();
79 private DbClient dbClient = dbTester.getDbClient();
80 private DbSession dbSession = dbTester.getSession();
81 private RuleIndex ruleIndex = new RuleIndex(es.client(), System2.INSTANCE);
82 private RuleIndexer ruleIndexer = new RuleIndexer(es.client(), dbClient);
83 private ActiveRuleIndexer activeRuleIndexer = new ActiveRuleIndexer(dbClient, es.client());
84 private TypeValidations typeValidations = new TypeValidations(emptyList());
85 private RuleActivator ruleActivator = new RuleActivator(System2.INSTANCE, dbClient, typeValidations, userSessionRule);
86 private QProfileRules qProfileRules = new QProfileRulesImpl(dbClient, ruleActivator, ruleIndex, activeRuleIndexer);
87 private final QProfileWsSupport qProfileWsSupport = new QProfileWsSupport(dbClient, userSessionRule);
88 private final RuleQueryFactory ruleQueryFactory = new RuleQueryFactory(dbClient);
90 private final WsActionTester wsDeactivateRule = new WsActionTester(new DeactivateRuleAction(dbClient, qProfileRules, userSessionRule, qProfileWsSupport));
91 private final WsActionTester wsDeactivateRules = new WsActionTester(new DeactivateRulesAction(ruleQueryFactory, userSessionRule, qProfileRules, qProfileWsSupport, dbClient));
92 private final WsActionTester wsActivateRule = new WsActionTester(new ActivateRuleAction(dbClient, qProfileRules, userSessionRule, qProfileWsSupport));
93 private final WsActionTester wsActivateRules = new WsActionTester(new ActivateRulesAction(ruleQueryFactory, userSessionRule, qProfileRules, qProfileWsSupport, dbClient));
96 public void deactivate_rule() {
97 QProfileDto profile = createProfile("java");
98 RuleDefinitionDto rule = createRule(profile.getLanguage(), "toto");
99 createActiveRule(rule, profile);
100 ruleIndexer.commitAndIndex(dbSession, rule.getUuid());
101 activeRuleIndexer.indexAll();
103 // 0. Assert No Active Rule for profile
104 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(1);
106 // 1. Deactivate Rule
107 wsDeactivateRule.newRequest().setMethod("POST")
108 .setParam(PARAM_KEY, profile.getKee())
109 .setParam(PARAM_RULE, rule.getKey().toString())
111 dbSession.clearCache();
113 // 2. Assert ActiveRule in DAO
114 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
118 public void bulk_deactivate_rule() {
119 QProfileDto profile = createProfile("java");
120 RuleDefinitionDto rule0 = createRule(profile.getLanguage(), "toto1");
121 RuleDefinitionDto rule1 = createRule(profile.getLanguage(), "toto2");
122 RuleDefinitionDto rule2 = createRule(profile.getLanguage(), "toto3");
123 RuleDefinitionDto rule3 = createRule(profile.getLanguage(), "toto4");
124 createActiveRule(rule0, profile);
125 createActiveRule(rule2, profile);
126 createActiveRule(rule3, profile);
127 createActiveRule(rule1, profile);
129 activeRuleIndexer.indexAll();
131 // 0. Assert No Active Rule for profile
132 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(4);
134 // 1. Deactivate Rule
135 wsDeactivateRules.newRequest().setMethod("POST")
136 .setParam(PARAM_TARGET_KEY, profile.getKee())
138 dbSession.clearCache();
140 // 2. Assert ActiveRule in DAO
141 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
145 public void bulk_deactivate_rule_not_all() {
146 QProfileDto profile = createProfile("java");
147 QProfileDto php = createProfile("php");
148 RuleDefinitionDto rule0 = createRule(profile.getLanguage(), "toto1");
149 RuleDefinitionDto rule1 = createRule(profile.getLanguage(), "toto2");
150 createActiveRule(rule0, profile);
151 createActiveRule(rule1, profile);
152 createActiveRule(rule0, php);
153 createActiveRule(rule1, php);
155 activeRuleIndexer.indexAll();
157 // 0. Assert No Active Rule for profile
158 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(2);
160 // 1. Deactivate Rule
161 wsDeactivateRules.newRequest().setMethod("POST")
162 .setParam(PARAM_TARGET_KEY, profile.getKee())
164 dbSession.clearCache();
166 // 2. Assert ActiveRule in DAO
167 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
168 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, php.getKee())).hasSize(2);
172 public void bulk_deactivate_rule_by_profile() {
173 QProfileDto profile = createProfile("java");
174 RuleDefinitionDto rule0 = createRule(profile.getLanguage(), "hello");
175 RuleDefinitionDto rule1 = createRule(profile.getLanguage(), "world");
176 createActiveRule(rule0, profile);
177 createActiveRule(rule1, profile);
179 activeRuleIndexer.indexAll();
181 // 0. Assert No Active Rule for profile
182 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(2);
184 // 1. Deactivate Rule
185 wsDeactivateRules.newRequest().setMethod("POST")
186 .setParam(PARAM_TARGET_KEY, profile.getKee())
187 .setParam(Param.TEXT_QUERY, "hello")
189 dbSession.clearCache();
191 // 2. Assert ActiveRule in DAO
192 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(1);
196 public void activate_rule() {
197 QProfileDto profile = createProfile("java");
198 RuleDefinitionDto rule = createRule(profile.getLanguage(), "toto");
199 ruleIndexer.commitAndIndex(dbSession, rule.getUuid());
201 // 0. Assert No Active Rule for profile
202 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
205 wsActivateRule.newRequest().setMethod("POST")
206 .setParam(PARAM_KEY, profile.getKee())
207 .setParam(PARAM_RULE, rule.getKey().toString())
209 dbSession.clearCache();
211 // 2. Assert ActiveRule in DAO
212 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(1);
216 public void activate_rule_diff_languages() {
217 QProfileDto profile = createProfile("java");
218 RuleDefinitionDto rule = createRule("php", "toto");
219 ruleIndexer.commitAndIndex(dbSession, rule.getUuid());
221 // 0. Assert No Active Rule for profile
222 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
226 wsActivateRule.newRequest().setMethod("POST")
227 .setParam(PARAM_KEY, profile.getKee())
228 .setParam(PARAM_RULE, rule.getKey().toString())
230 dbSession.clearCache();
232 } catch (BadRequestException e) {
233 assertThat(e.getMessage()).isEqualTo("php rule blah:toto cannot be activated on java profile Pjava");
238 public void activate_rule_override_severity() {
239 QProfileDto profile = createProfile("java");
240 RuleDefinitionDto rule = createRule(profile.getLanguage(), "toto");
241 ruleIndexer.commitAndIndex(dbSession, rule.getUuid());
243 // 0. Assert No Active Rule for profile
244 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
247 wsActivateRule.newRequest().setMethod("POST")
248 .setParam(PARAM_KEY, profile.getKee())
249 .setParam(PARAM_RULE, rule.getKey().toString())
250 .setParam(PARAM_SEVERITY, "MINOR")
252 dbSession.clearCache();
254 // 2. Assert ActiveRule in DAO
255 ActiveRuleKey activeRuleKey = ActiveRuleKey.of(profile, rule.getKey());
257 Optional<ActiveRuleDto> activeRuleDto = dbClient.activeRuleDao().selectByKey(dbSession, activeRuleKey);
258 assertThat(activeRuleDto.isPresent()).isTrue();
259 assertThat(activeRuleDto.get().getSeverityString()).isEqualTo(Severity.MINOR);
263 public void bulk_activate_rule() {
264 QProfileDto profile = createProfile("java");
265 createRule(profile.getLanguage(), "toto");
266 createRule(profile.getLanguage(), "tata");
267 createRule(profile.getLanguage(), "hello");
268 createRule(profile.getLanguage(), "world");
271 // 0. Assert No Active Rule for profile
272 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
275 wsActivateRules.newRequest().setMethod("POST")
276 .setParam(PARAM_TARGET_KEY, profile.getKee())
277 .setParam(PARAM_LANGUAGES, "java")
279 .assertJson(getClass(), "bulk_activate_rule.json");
280 dbSession.clearCache();
282 // 2. Assert ActiveRule in DAO
283 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(4);
287 public void bulk_activate_rule_not_all() {
288 QProfileDto java = createProfile("java");
289 QProfileDto php = createProfile("php");
290 createRule(java.getLanguage(), "toto");
291 createRule(java.getLanguage(), "tata");
292 createRule(php.getLanguage(), "hello");
293 createRule(php.getLanguage(), "world");
296 // 0. Assert No Active Rule for profile
297 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, php.getKee())).isEmpty();
300 wsActivateRules.newRequest().setMethod("POST")
301 .setParam(PARAM_TARGET_KEY, php.getKee())
302 .setParam(PARAM_LANGUAGES, "php")
304 .assertJson(getClass(), "bulk_activate_rule_not_all.json");
305 dbSession.clearCache();
307 // 2. Assert ActiveRule in DAO
308 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, php.getKee())).hasSize(2);
312 public void bulk_activate_rule_by_query() {
313 QProfileDto profile = createProfile("java");
314 createRule(profile.getLanguage(), "toto");
315 createRule(profile.getLanguage(), "tata");
316 createRule(profile.getLanguage(), "hello");
317 createRule(profile.getLanguage(), "world");
320 // 0. Assert No Active Rule for profile
321 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
323 // 1. Activate Rule with query returning 0 hits
324 wsActivateRules.newRequest().setMethod("POST")
325 .setParam(PARAM_TARGET_KEY, profile.getKee())
326 .setParam(Param.TEXT_QUERY, "php")
328 dbSession.clearCache();
330 // 2. Assert ActiveRule in DAO
331 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
333 // 1. Activate Rule with query returning 1 hits
334 wsActivateRules.newRequest().setMethod("POST")
335 .setParam(PARAM_TARGET_KEY, profile.getKee())
336 .setParam(Param.TEXT_QUERY, "world")
340 // 2. Assert ActiveRule in DAO
341 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(1);
345 public void bulk_activate_rule_by_query_with_severity() {
346 QProfileDto profile = createProfile("java");
347 RuleDefinitionDto rule0 = createRule(profile.getLanguage(), "toto");
348 RuleDefinitionDto rule1 = createRule(profile.getLanguage(), "tata");
351 // 0. Assert No Active Rule for profile
352 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
354 // 2. Assert ActiveRule with BLOCKER severity
355 assertThat(ruleIndex.search(
356 new RuleQuery().setSeverities(ImmutableSet.of("BLOCKER")),
357 new SearchOptions()).getUuids()).hasSize(2);
359 // 1. Activate Rule with query returning 2 hits
360 wsActivateRules.newRequest().setMethod("POST")
361 .setParam(PARAM_TARGET_KEY, profile.getKee())
362 .setParam(PARAM_TARGET_SEVERITY, "MINOR")
366 // 2. Assert ActiveRule with MINOR severity
367 assertThat(dbClient.activeRuleDao().selectByOrgRuleUuid(dbSession, rule0.getUuid()).get(0).getSeverityString()).isEqualTo("MINOR");
368 assertThat(ruleIndex.searchAll(new RuleQuery()
369 .setQProfile(profile)
370 .setKey(rule0.getKey().toString())
371 .setActiveSeverities(Collections.singleton("MINOR"))
372 .setActivation(true))).toIterable().hasSize(1);
376 public void does_not_return_warnings_when_bulk_activate_on_profile_and_rules_exist_on_another_language_than_profile() {
377 QProfileDto javaProfile = createProfile("java");
378 createRule(javaProfile.getLanguage(), "toto");
379 createRule(javaProfile.getLanguage(), "tata");
380 QProfileDto phpProfile = createProfile("php");
381 createRule(phpProfile.getLanguage(), "hello");
382 createRule(phpProfile.getLanguage(), "world");
386 wsActivateRules.newRequest().setMethod("POST")
387 .setParam(PARAM_TARGET_KEY, javaProfile.getKee())
388 .setParam(PARAM_QPROFILE, javaProfile.getKee())
389 .setParam("activation", "false")
391 .assertJson(getClass(), "does_not_return_warnings_when_bulk_activate_on_profile_and_rules_exist_on_another_language_than_profile.json");
392 dbSession.clearCache();
394 // 2. Assert ActiveRule in DAO
395 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, javaProfile.getKee())).hasSize(2);
399 public void reset() {
400 QProfileDto profile = QProfileTesting.newXooP1();
401 QProfileDto childProfile = QProfileTesting.newXooP2().setParentKee(QProfileTesting.XOO_P1_KEY);
402 dbClient.qualityProfileDao().insert(dbSession, profile, childProfile);
404 RuleDefinitionDto rule = createRule(profile.getLanguage(), "rule");
405 ActiveRuleDto active1 = ActiveRuleDto.createFor(profile, rule)
406 .setSeverity(rule.getSeverityString());
407 ActiveRuleDto active2 = ActiveRuleDto.createFor(childProfile, rule)
408 .setSeverity("MINOR");
409 dbClient.activeRuleDao().insert(dbSession, active1);
410 dbClient.activeRuleDao().insert(dbSession, active2);
413 activeRuleIndexer.indexAll();
415 // 0. assert rule child rule is minor
416 Optional<ActiveRuleDto> activeRuleDto = dbClient.activeRuleDao().selectByKey(dbSession, active2.getKey());
417 assertThat(activeRuleDto.isPresent()).isTrue();
418 assertThat(activeRuleDto.get().getSeverityString()).isEqualTo(Severity.MINOR);
420 // 1. reset child rule
421 wsActivateRule.newRequest().setMethod("POST")
422 .setParam(PARAM_KEY, childProfile.getKee())
423 .setParam(PARAM_RULE, rule.getKey().toString())
424 .setParam(PARAM_RESET, "true")
426 dbSession.clearCache();
428 // 2. assert rule child rule is NOT minor
429 activeRuleDto = dbClient.activeRuleDao().selectByKey(dbSession, active2.getKey());
430 assertThat(activeRuleDto.isPresent()).isTrue();
431 assertThat(activeRuleDto.get().getSeverityString()).isNotEqualTo(Severity.MINOR);
434 private QProfileDto createProfile(String lang) {
435 QProfileDto profile = QProfileTesting.newQProfileDto(new QProfileName(lang, "P" + lang), "p" + lang);
436 dbClient.qualityProfileDao().insert(dbSession, profile);
440 private RuleDefinitionDto createRule(String lang, String id) {
441 RuleDefinitionDto rule = RuleTesting.newRule(RuleKey.of("blah", id))
443 .setSeverity(Severity.BLOCKER)
444 .setStatus(RuleStatus.READY);
445 dbClient.ruleDao().insert(dbSession, rule);
446 ruleIndexer.commitAndIndex(dbSession, rule.getUuid());
450 private ActiveRuleDto createActiveRule(RuleDefinitionDto rule, QProfileDto profile) {
451 ActiveRuleDto activeRule = ActiveRuleDto.createFor(profile, rule)
452 .setSeverity(rule.getSeverityString());
453 dbClient.activeRuleDao().insert(dbSession, activeRule);