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.Before;
26 import org.junit.Rule;
27 import org.junit.Test;
28 import org.sonar.api.rule.RuleKey;
29 import org.sonar.api.rule.RuleStatus;
30 import org.sonar.api.rule.Severity;
31 import org.sonar.api.server.ws.WebService.Param;
32 import org.sonar.api.utils.System2;
33 import org.sonar.db.DbClient;
34 import org.sonar.db.DbSession;
35 import org.sonar.db.DbTester;
36 import org.sonar.db.organization.OrganizationDto;
37 import org.sonar.db.qualityprofile.ActiveRuleDto;
38 import org.sonar.db.qualityprofile.ActiveRuleKey;
39 import org.sonar.db.qualityprofile.QProfileDto;
40 import org.sonar.db.rule.RuleDefinitionDto;
41 import org.sonar.db.rule.RuleTesting;
42 import org.sonar.server.es.EsTester;
43 import org.sonar.server.es.SearchOptions;
44 import org.sonar.server.exceptions.BadRequestException;
45 import org.sonar.server.organization.DefaultOrganizationProvider;
46 import org.sonar.server.organization.TestDefaultOrganizationProvider;
47 import org.sonar.server.qualityprofile.QProfileName;
48 import org.sonar.server.qualityprofile.QProfileRules;
49 import org.sonar.server.qualityprofile.QProfileRulesImpl;
50 import org.sonar.server.qualityprofile.QProfileTesting;
51 import org.sonar.server.qualityprofile.RuleActivator;
52 import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
53 import org.sonar.server.rule.index.RuleIndex;
54 import org.sonar.server.rule.index.RuleIndexer;
55 import org.sonar.server.rule.index.RuleQuery;
56 import org.sonar.server.rule.ws.RuleQueryFactory;
57 import org.sonar.server.tester.UserSessionRule;
58 import org.sonar.server.util.TypeValidations;
59 import org.sonar.server.ws.WsActionTester;
61 import static java.util.Collections.emptyList;
62 import static org.assertj.core.api.Assertions.assertThat;
63 import static org.junit.Assert.fail;
64 import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_LANGUAGES;
65 import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_QPROFILE;
66 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_KEY;
67 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_RESET;
68 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_RULE;
69 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_SEVERITY;
70 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_TARGET_KEY;
71 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_TARGET_SEVERITY;
73 public class QProfilesWsMediumTest {
76 public UserSessionRule userSessionRule = UserSessionRule.standalone()
79 public EsTester es = EsTester.create();
81 public DbTester dbTester = DbTester.create();
83 private DbClient dbClient = dbTester.getDbClient();
84 private DbSession dbSession = dbTester.getSession();
85 private RuleIndex ruleIndex = new RuleIndex(es.client(), System2.INSTANCE);
86 private RuleIndexer ruleIndexer = new RuleIndexer(es.client(), dbClient);
87 private ActiveRuleIndexer activeRuleIndexer = new ActiveRuleIndexer(dbClient, es.client());
88 private TypeValidations typeValidations = new TypeValidations(emptyList());
89 private RuleActivator ruleActivator = new RuleActivator(System2.INSTANCE, dbClient, typeValidations, userSessionRule);
90 private QProfileRules qProfileRules = new QProfileRulesImpl(dbClient, ruleActivator, ruleIndex, activeRuleIndexer);
91 private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(dbTester);
92 private QProfileWsSupport qProfileWsSupport = new QProfileWsSupport(dbClient, userSessionRule, defaultOrganizationProvider);
93 private RuleQueryFactory ruleQueryFactory = new RuleQueryFactory(dbClient);
94 private OrganizationDto organization;
96 private WsActionTester wsDeactivateRule = new WsActionTester(new DeactivateRuleAction(dbClient, qProfileRules, userSessionRule, qProfileWsSupport));
97 private WsActionTester wsDeactivateRules = new WsActionTester(new DeactivateRulesAction(ruleQueryFactory, userSessionRule, qProfileRules, qProfileWsSupport, dbClient));
98 private WsActionTester wsActivateRule = new WsActionTester(new ActivateRuleAction(dbClient, qProfileRules, userSessionRule, qProfileWsSupport));
99 private WsActionTester wsActivateRules = new WsActionTester(new ActivateRulesAction(ruleQueryFactory, userSessionRule, qProfileRules, qProfileWsSupport, dbClient));
102 public void setUp() {
103 organization = dbTester.organizations().insert();
107 public void deactivate_rule() {
108 QProfileDto profile = createProfile("java");
109 RuleDefinitionDto rule = createRule(profile.getLanguage(), "toto");
110 createActiveRule(rule, profile);
111 ruleIndexer.commitAndIndex(dbSession, rule.getUuid());
112 activeRuleIndexer.indexOnStartup(activeRuleIndexer.getIndexTypes());
114 // 0. Assert No Active Rule for profile
115 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(1);
117 // 1. Deactivate Rule
118 wsDeactivateRule.newRequest().setMethod("POST")
119 .setParam(PARAM_KEY, profile.getKee())
120 .setParam(PARAM_RULE, rule.getKey().toString())
122 dbSession.clearCache();
124 // 2. Assert ActiveRule in DAO
125 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
129 public void bulk_deactivate_rule() {
130 QProfileDto profile = createProfile("java");
131 RuleDefinitionDto rule0 = createRule(profile.getLanguage(), "toto1");
132 RuleDefinitionDto rule1 = createRule(profile.getLanguage(), "toto2");
133 RuleDefinitionDto rule2 = createRule(profile.getLanguage(), "toto3");
134 RuleDefinitionDto rule3 = createRule(profile.getLanguage(), "toto4");
135 createActiveRule(rule0, profile);
136 createActiveRule(rule2, profile);
137 createActiveRule(rule3, profile);
138 createActiveRule(rule1, profile);
140 activeRuleIndexer.indexOnStartup(activeRuleIndexer.getIndexTypes());
142 // 0. Assert No Active Rule for profile
143 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(4);
145 // 1. Deactivate Rule
146 wsDeactivateRules.newRequest().setMethod("POST")
147 .setParam(PARAM_TARGET_KEY, profile.getKee())
149 dbSession.clearCache();
151 // 2. Assert ActiveRule in DAO
152 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
156 public void bulk_deactivate_rule_not_all() {
157 QProfileDto profile = createProfile("java");
158 QProfileDto php = createProfile("php");
159 RuleDefinitionDto rule0 = createRule(profile.getLanguage(), "toto1");
160 RuleDefinitionDto rule1 = createRule(profile.getLanguage(), "toto2");
161 createActiveRule(rule0, profile);
162 createActiveRule(rule1, profile);
163 createActiveRule(rule0, php);
164 createActiveRule(rule1, php);
166 activeRuleIndexer.indexOnStartup(activeRuleIndexer.getIndexTypes());
168 // 0. Assert No Active Rule for profile
169 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(2);
171 // 1. Deactivate Rule
172 wsDeactivateRules.newRequest().setMethod("POST")
173 .setParam(PARAM_TARGET_KEY, profile.getKee())
175 dbSession.clearCache();
177 // 2. Assert ActiveRule in DAO
178 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(0);
179 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, php.getKee())).hasSize(2);
183 public void bulk_deactivate_rule_by_profile() {
184 QProfileDto profile = createProfile("java");
185 RuleDefinitionDto rule0 = createRule(profile.getLanguage(), "hello");
186 RuleDefinitionDto rule1 = createRule(profile.getLanguage(), "world");
187 createActiveRule(rule0, profile);
188 createActiveRule(rule1, profile);
190 activeRuleIndexer.indexOnStartup(activeRuleIndexer.getIndexTypes());
192 // 0. Assert No Active Rule for profile
193 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(2);
195 // 1. Deactivate Rule
196 wsDeactivateRules.newRequest().setMethod("POST")
197 .setParam(PARAM_TARGET_KEY, profile.getKee())
198 .setParam(Param.TEXT_QUERY, "hello")
200 dbSession.clearCache();
202 // 2. Assert ActiveRule in DAO
203 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(1);
207 public void activate_rule() {
208 QProfileDto profile = createProfile("java");
209 RuleDefinitionDto rule = createRule(profile.getLanguage(), "toto");
210 ruleIndexer.commitAndIndex(dbSession, rule.getUuid());
212 // 0. Assert No Active Rule for profile
213 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
216 wsActivateRule.newRequest().setMethod("POST")
217 .setParam(PARAM_KEY, profile.getKee())
218 .setParam(PARAM_RULE, rule.getKey().toString())
220 dbSession.clearCache();
222 // 2. Assert ActiveRule in DAO
223 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(1);
227 public void activate_rule_diff_languages() {
228 QProfileDto profile = createProfile("java");
229 RuleDefinitionDto rule = createRule("php", "toto");
230 ruleIndexer.commitAndIndex(dbSession, rule.getUuid());
232 // 0. Assert No Active Rule for profile
233 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
237 wsActivateRule.newRequest().setMethod("POST")
238 .setParam(PARAM_KEY, profile.getKee())
239 .setParam(PARAM_RULE, rule.getKey().toString())
241 dbSession.clearCache();
243 } catch (BadRequestException e) {
244 assertThat(e.getMessage()).isEqualTo("php rule blah:toto cannot be activated on java profile Pjava");
249 public void activate_rule_override_severity() {
250 QProfileDto profile = createProfile("java");
251 RuleDefinitionDto rule = createRule(profile.getLanguage(), "toto");
252 ruleIndexer.commitAndIndex(dbSession, rule.getUuid());
254 // 0. Assert No Active Rule for profile
255 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
258 wsActivateRule.newRequest().setMethod("POST")
259 .setParam(PARAM_KEY, profile.getKee())
260 .setParam(PARAM_RULE, rule.getKey().toString())
261 .setParam(PARAM_SEVERITY, "MINOR")
263 dbSession.clearCache();
265 // 2. Assert ActiveRule in DAO
266 ActiveRuleKey activeRuleKey = ActiveRuleKey.of(profile, rule.getKey());
268 Optional<ActiveRuleDto> activeRuleDto = dbClient.activeRuleDao().selectByKey(dbSession, activeRuleKey);
269 assertThat(activeRuleDto.isPresent()).isTrue();
270 assertThat(activeRuleDto.get().getSeverityString()).isEqualTo(Severity.MINOR);
274 public void bulk_activate_rule() {
275 QProfileDto profile = createProfile("java");
276 createRule(profile.getLanguage(), "toto");
277 createRule(profile.getLanguage(), "tata");
278 createRule(profile.getLanguage(), "hello");
279 createRule(profile.getLanguage(), "world");
282 // 0. Assert No Active Rule for profile
283 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
286 wsActivateRules.newRequest().setMethod("POST")
287 .setParam(PARAM_TARGET_KEY, profile.getKee())
288 .setParam(PARAM_LANGUAGES, "java")
290 .assertJson(getClass(), "bulk_activate_rule.json");
291 dbSession.clearCache();
293 // 2. Assert ActiveRule in DAO
294 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(4);
298 public void bulk_activate_rule_not_all() {
299 QProfileDto java = createProfile("java");
300 QProfileDto php = createProfile("php");
301 createRule(java.getLanguage(), "toto");
302 createRule(java.getLanguage(), "tata");
303 createRule(php.getLanguage(), "hello");
304 createRule(php.getLanguage(), "world");
307 // 0. Assert No Active Rule for profile
308 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, php.getKee())).isEmpty();
311 wsActivateRules.newRequest().setMethod("POST")
312 .setParam(PARAM_TARGET_KEY, php.getKee())
313 .setParam(PARAM_LANGUAGES, "php")
315 .assertJson(getClass(), "bulk_activate_rule_not_all.json");
316 dbSession.clearCache();
318 // 2. Assert ActiveRule in DAO
319 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, php.getKee())).hasSize(2);
323 public void bulk_activate_rule_by_query() {
324 QProfileDto profile = createProfile("java");
325 createRule(profile.getLanguage(), "toto");
326 createRule(profile.getLanguage(), "tata");
327 createRule(profile.getLanguage(), "hello");
328 createRule(profile.getLanguage(), "world");
331 // 0. Assert No Active Rule for profile
332 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
334 // 1. Activate Rule with query returning 0 hits
335 wsActivateRules.newRequest().setMethod("POST")
336 .setParam(PARAM_TARGET_KEY, profile.getKee())
337 .setParam(Param.TEXT_QUERY, "php")
339 dbSession.clearCache();
341 // 2. Assert ActiveRule in DAO
342 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(0);
344 // 1. Activate Rule with query returning 1 hits
345 wsActivateRules.newRequest().setMethod("POST")
346 .setParam(PARAM_TARGET_KEY, profile.getKee())
347 .setParam(Param.TEXT_QUERY, "world")
351 // 2. Assert ActiveRule in DAO
352 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(1);
356 public void bulk_activate_rule_by_query_with_severity() {
357 QProfileDto profile = createProfile("java");
358 RuleDefinitionDto rule0 = createRule(profile.getLanguage(), "toto");
359 RuleDefinitionDto rule1 = createRule(profile.getLanguage(), "tata");
362 // 0. Assert No Active Rule for profile
363 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
365 // 2. Assert ActiveRule with BLOCKER severity
366 assertThat(ruleIndex.search(
367 new RuleQuery().setSeverities(ImmutableSet.of("BLOCKER")),
368 new SearchOptions()).getUuids()).hasSize(2);
370 // 1. Activate Rule with query returning 2 hits
371 wsActivateRules.newRequest().setMethod("POST")
372 .setParam(PARAM_TARGET_KEY, profile.getKee())
373 .setParam(PARAM_TARGET_SEVERITY, "MINOR")
377 // 2. Assert ActiveRule with MINOR severity
378 assertThat(dbClient.activeRuleDao().selectByOrgRuleUuid(dbSession, rule0.getUuid()).get(0).getSeverityString()).isEqualTo("MINOR");
379 assertThat(ruleIndex.searchAll(new RuleQuery()
380 .setQProfile(profile)
381 .setKey(rule0.getKey().toString())
382 .setActiveSeverities(Collections.singleton("MINOR"))
383 .setActivation(true))).toIterable().hasSize(1);
387 public void does_not_return_warnings_when_bulk_activate_on_profile_and_rules_exist_on_another_language_than_profile() {
388 QProfileDto javaProfile = createProfile("java");
389 createRule(javaProfile.getLanguage(), "toto");
390 createRule(javaProfile.getLanguage(), "tata");
391 QProfileDto phpProfile = createProfile("php");
392 createRule(phpProfile.getLanguage(), "hello");
393 createRule(phpProfile.getLanguage(), "world");
397 wsActivateRules.newRequest().setMethod("POST")
398 .setParam(PARAM_TARGET_KEY, javaProfile.getKee())
399 .setParam(PARAM_QPROFILE, javaProfile.getKee())
400 .setParam("activation", "false")
402 .assertJson(getClass(), "does_not_return_warnings_when_bulk_activate_on_profile_and_rules_exist_on_another_language_than_profile.json");
403 dbSession.clearCache();
405 // 2. Assert ActiveRule in DAO
406 assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, javaProfile.getKee())).hasSize(2);
410 public void reset() {
411 QProfileDto profile = QProfileTesting.newXooP1();
412 QProfileDto childProfile = QProfileTesting.newXooP2().setParentKee(QProfileTesting.XOO_P1_KEY);
413 dbClient.qualityProfileDao().insert(dbSession, profile, childProfile);
415 RuleDefinitionDto rule = createRule(profile.getLanguage(), "rule");
416 ActiveRuleDto active1 = ActiveRuleDto.createFor(profile, rule)
417 .setSeverity(rule.getSeverityString());
418 ActiveRuleDto active2 = ActiveRuleDto.createFor(childProfile, rule)
419 .setSeverity("MINOR");
420 dbClient.activeRuleDao().insert(dbSession, active1);
421 dbClient.activeRuleDao().insert(dbSession, active2);
424 activeRuleIndexer.indexOnStartup(activeRuleIndexer.getIndexTypes());
426 // 0. assert rule child rule is minor
427 Optional<ActiveRuleDto> activeRuleDto = dbClient.activeRuleDao().selectByKey(dbSession, active2.getKey());
428 assertThat(activeRuleDto.isPresent()).isTrue();
429 assertThat(activeRuleDto.get().getSeverityString()).isEqualTo(Severity.MINOR);
431 // 1. reset child rule
432 wsActivateRule.newRequest().setMethod("POST")
433 .setParam(PARAM_KEY, childProfile.getKee())
434 .setParam(PARAM_RULE, rule.getKey().toString())
435 .setParam(PARAM_RESET, "true")
437 dbSession.clearCache();
439 // 2. assert rule child rule is NOT minor
440 activeRuleDto = dbClient.activeRuleDao().selectByKey(dbSession, active2.getKey());
441 assertThat(activeRuleDto.isPresent()).isTrue();
442 assertThat(activeRuleDto.get().getSeverityString()).isNotEqualTo(Severity.MINOR);
445 private QProfileDto createProfile(String lang) {
446 QProfileDto profile = QProfileTesting.newQProfileDto(new QProfileName(lang, "P" + lang), "p" + lang);
447 dbClient.qualityProfileDao().insert(dbSession, profile);
451 private RuleDefinitionDto createRule(String lang, String id) {
452 RuleDefinitionDto rule = RuleTesting.newRule(RuleKey.of("blah", id))
454 .setSeverity(Severity.BLOCKER)
455 .setStatus(RuleStatus.READY);
456 dbClient.ruleDao().insert(dbSession, rule);
457 ruleIndexer.commitAndIndex(dbSession, rule.getUuid());
461 private ActiveRuleDto createActiveRule(RuleDefinitionDto rule, QProfileDto profile) {
462 ActiveRuleDto activeRule = ActiveRuleDto.createFor(profile, rule)
463 .setSeverity(rule.getSeverityString());
464 dbClient.activeRuleDao().insert(dbSession, activeRule);