]> source.dussan.org Git - sonarqube.git/blob
7159997ddc11056564cffdad782b6b55b4757181
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2022 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.ws;
21
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.qualityprofile.QualityProfileTesting;
39 import org.sonar.db.rule.RuleDefinitionDto;
40 import org.sonar.db.rule.RuleTesting;
41 import org.sonar.server.es.EsTester;
42 import org.sonar.server.es.SearchOptions;
43 import org.sonar.server.exceptions.BadRequestException;
44 import org.sonar.server.pushapi.qualityprofile.QualityProfileChangeEventService;
45 import org.sonar.server.qualityprofile.QProfileRules;
46 import org.sonar.server.qualityprofile.QProfileRulesImpl;
47 import org.sonar.server.qualityprofile.builtin.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;
56
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.mockito.Mockito.mock;
61 import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_LANGUAGES;
62 import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_QPROFILE;
63 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_KEY;
64 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_RESET;
65 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_RULE;
66 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_SEVERITY;
67 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_TARGET_KEY;
68 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_TARGET_SEVERITY;
69
70 public class QProfilesWsMediumTest {
71
72   @Rule
73   public UserSessionRule userSessionRule = UserSessionRule.standalone()
74     .logIn().setRoot();
75   @Rule
76   public EsTester es = EsTester.create();
77   @Rule
78   public DbTester dbTester = DbTester.create();
79
80   private final DbClient dbClient = dbTester.getDbClient();
81   private final DbSession dbSession = dbTester.getSession();
82   private final RuleIndex ruleIndex = new RuleIndex(es.client(), System2.INSTANCE);
83   private final RuleIndexer ruleIndexer = new RuleIndexer(es.client(), dbClient);
84   private final ActiveRuleIndexer activeRuleIndexer = new ActiveRuleIndexer(dbClient, es.client());
85   private final TypeValidations typeValidations = new TypeValidations(emptyList());
86   private final QualityProfileChangeEventService qualityProfileChangeEventService = mock(QualityProfileChangeEventService.class);
87   private final RuleActivator ruleActivator = new RuleActivator(System2.INSTANCE, dbClient, typeValidations, userSessionRule);
88   private final QProfileRules qProfileRules = new QProfileRulesImpl(dbClient, ruleActivator, ruleIndex, activeRuleIndexer, qualityProfileChangeEventService);
89   private final QProfileWsSupport qProfileWsSupport = new QProfileWsSupport(dbClient, userSessionRule);
90   private final RuleQueryFactory ruleQueryFactory = new RuleQueryFactory(dbClient);
91
92   private final WsActionTester wsDeactivateRule = new WsActionTester(new DeactivateRuleAction(dbClient, qProfileRules, userSessionRule, qProfileWsSupport));
93   private final WsActionTester wsDeactivateRules = new WsActionTester(new DeactivateRulesAction(ruleQueryFactory, userSessionRule, qProfileRules, qProfileWsSupport, dbClient));
94   private final WsActionTester wsActivateRule = new WsActionTester(new ActivateRuleAction(dbClient, qProfileRules, userSessionRule, qProfileWsSupport));
95   private final WsActionTester wsActivateRules = new WsActionTester(new ActivateRulesAction(ruleQueryFactory, userSessionRule, qProfileRules, qProfileWsSupport, dbClient));
96
97   @Test
98   public void deactivate_rule() {
99     QProfileDto profile = createProfile("java");
100     RuleDefinitionDto rule = createRule(profile.getLanguage(), "toto");
101     createActiveRule(rule, profile);
102     ruleIndexer.commitAndIndex(dbSession, rule.getUuid());
103     activeRuleIndexer.indexAll();
104
105     // 0. Assert No Active Rule for profile
106     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(1);
107
108     // 1. Deactivate Rule
109     wsDeactivateRule.newRequest().setMethod("POST")
110       .setParam(PARAM_KEY, profile.getKee())
111       .setParam(PARAM_RULE, rule.getKey().toString())
112       .execute();
113     dbSession.clearCache();
114
115     // 2. Assert ActiveRule in DAO
116     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
117   }
118
119   @Test
120   public void bulk_deactivate_rule() {
121     QProfileDto profile = createProfile("java");
122     RuleDefinitionDto rule0 = createRule(profile.getLanguage(), "toto1");
123     RuleDefinitionDto rule1 = createRule(profile.getLanguage(), "toto2");
124     RuleDefinitionDto rule2 = createRule(profile.getLanguage(), "toto3");
125     RuleDefinitionDto rule3 = createRule(profile.getLanguage(), "toto4");
126     createActiveRule(rule0, profile);
127     createActiveRule(rule2, profile);
128     createActiveRule(rule3, profile);
129     createActiveRule(rule1, profile);
130     dbSession.commit();
131     activeRuleIndexer.indexAll();
132
133     // 0. Assert No Active Rule for profile
134     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(4);
135
136     // 1. Deactivate Rule
137     wsDeactivateRules.newRequest().setMethod("POST")
138       .setParam(PARAM_TARGET_KEY, profile.getKee())
139       .execute();
140     dbSession.clearCache();
141
142     // 2. Assert ActiveRule in DAO
143     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
144   }
145
146   @Test
147   public void bulk_deactivate_rule_not_all() {
148     QProfileDto profile = createProfile("java");
149     QProfileDto php = createProfile("php");
150     RuleDefinitionDto rule0 = createRule(profile.getLanguage(), "toto1");
151     RuleDefinitionDto rule1 = createRule(profile.getLanguage(), "toto2");
152     createActiveRule(rule0, profile);
153     createActiveRule(rule1, profile);
154     createActiveRule(rule0, php);
155     createActiveRule(rule1, php);
156     dbSession.commit();
157     activeRuleIndexer.indexAll();
158
159     // 0. Assert No Active Rule for profile
160     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(2);
161
162     // 1. Deactivate Rule
163     wsDeactivateRules.newRequest().setMethod("POST")
164       .setParam(PARAM_TARGET_KEY, profile.getKee())
165       .execute();
166     dbSession.clearCache();
167
168     // 2. Assert ActiveRule in DAO
169     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
170     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, php.getKee())).hasSize(2);
171   }
172
173   @Test
174   public void bulk_deactivate_rule_by_profile() {
175     QProfileDto profile = createProfile("java");
176     RuleDefinitionDto rule0 = createRule(profile.getLanguage(), "hello");
177     RuleDefinitionDto rule1 = createRule(profile.getLanguage(), "world");
178     createActiveRule(rule0, profile);
179     createActiveRule(rule1, profile);
180     dbSession.commit();
181     activeRuleIndexer.indexAll();
182
183     // 0. Assert No Active Rule for profile
184     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(2);
185
186     // 1. Deactivate Rule
187     wsDeactivateRules.newRequest().setMethod("POST")
188       .setParam(PARAM_TARGET_KEY, profile.getKee())
189       .setParam(Param.TEXT_QUERY, "hello")
190       .execute();
191     dbSession.clearCache();
192
193     // 2. Assert ActiveRule in DAO
194     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(1);
195   }
196
197   @Test
198   public void activate_rule() {
199     QProfileDto profile = createProfile("java");
200     RuleDefinitionDto rule = createRule(profile.getLanguage(), "toto");
201     ruleIndexer.commitAndIndex(dbSession, rule.getUuid());
202
203     // 0. Assert No Active Rule for profile
204     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
205
206     // 1. Activate Rule
207     wsActivateRule.newRequest().setMethod("POST")
208       .setParam(PARAM_KEY, profile.getKee())
209       .setParam(PARAM_RULE, rule.getKey().toString())
210       .execute();
211     dbSession.clearCache();
212
213     // 2. Assert ActiveRule in DAO
214     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(1);
215   }
216
217   @Test
218   public void activate_rule_diff_languages() {
219     QProfileDto profile = createProfile("java");
220     RuleDefinitionDto rule = createRule("php", "toto");
221     ruleIndexer.commitAndIndex(dbSession, rule.getUuid());
222
223     // 0. Assert No Active Rule for profile
224     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
225
226     try {
227       // 1. Activate Rule
228       wsActivateRule.newRequest().setMethod("POST")
229         .setParam(PARAM_KEY, profile.getKee())
230         .setParam(PARAM_RULE, rule.getKey().toString())
231         .execute();
232       dbSession.clearCache();
233       fail();
234     } catch (BadRequestException e) {
235       assertThat(e.getMessage()).isEqualTo("php rule blah:toto cannot be activated on java profile Pjava");
236     }
237   }
238
239   @Test
240   public void activate_rule_override_severity() {
241     QProfileDto profile = createProfile("java");
242     RuleDefinitionDto rule = createRule(profile.getLanguage(), "toto");
243     ruleIndexer.commitAndIndex(dbSession, rule.getUuid());
244
245     // 0. Assert No Active Rule for profile
246     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
247
248     // 1. Activate Rule
249     wsActivateRule.newRequest().setMethod("POST")
250       .setParam(PARAM_KEY, profile.getKee())
251       .setParam(PARAM_RULE, rule.getKey().toString())
252       .setParam(PARAM_SEVERITY, "MINOR")
253       .execute();
254     dbSession.clearCache();
255
256     // 2. Assert ActiveRule in DAO
257     ActiveRuleKey activeRuleKey = ActiveRuleKey.of(profile, rule.getKey());
258
259     Optional<ActiveRuleDto> activeRuleDto = dbClient.activeRuleDao().selectByKey(dbSession, activeRuleKey);
260     assertThat(activeRuleDto).isPresent();
261     assertThat(activeRuleDto.get().getSeverityString()).isEqualTo(Severity.MINOR);
262   }
263
264   @Test
265   public void bulk_activate_rule() {
266     QProfileDto profile = createProfile("java");
267     createRule(profile.getLanguage(), "toto");
268     createRule(profile.getLanguage(), "tata");
269     createRule(profile.getLanguage(), "hello");
270     createRule(profile.getLanguage(), "world");
271     dbSession.commit();
272
273     // 0. Assert No Active Rule for profile
274     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
275
276     // 1. Activate Rule
277     wsActivateRules.newRequest().setMethod("POST")
278       .setParam(PARAM_TARGET_KEY, profile.getKee())
279       .setParam(PARAM_LANGUAGES, "java")
280       .execute()
281       .assertJson(getClass(), "bulk_activate_rule.json");
282     dbSession.clearCache();
283
284     // 2. Assert ActiveRule in DAO
285     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(4);
286   }
287
288   @Test
289   public void bulk_activate_rule_not_all() {
290     QProfileDto java = createProfile("java");
291     QProfileDto php = createProfile("php");
292     createRule(java.getLanguage(), "toto");
293     createRule(java.getLanguage(), "tata");
294     createRule(php.getLanguage(), "hello");
295     createRule(php.getLanguage(), "world");
296     dbSession.commit();
297
298     // 0. Assert No Active Rule for profile
299     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, php.getKee())).isEmpty();
300
301     // 1. Activate Rule
302     wsActivateRules.newRequest().setMethod("POST")
303       .setParam(PARAM_TARGET_KEY, php.getKee())
304       .setParam(PARAM_LANGUAGES, "php")
305       .execute()
306       .assertJson(getClass(), "bulk_activate_rule_not_all.json");
307     dbSession.clearCache();
308
309     // 2. Assert ActiveRule in DAO
310     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, php.getKee())).hasSize(2);
311   }
312
313   @Test
314   public void bulk_activate_rule_by_query() {
315     QProfileDto profile = createProfile("java");
316     createRule(profile.getLanguage(), "toto");
317     createRule(profile.getLanguage(), "tata");
318     createRule(profile.getLanguage(), "hello");
319     createRule(profile.getLanguage(), "world");
320     dbSession.commit();
321
322     // 0. Assert No Active Rule for profile
323     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
324
325     // 1. Activate Rule with query returning 0 hits
326     wsActivateRules.newRequest().setMethod("POST")
327       .setParam(PARAM_TARGET_KEY, profile.getKee())
328       .setParam(Param.TEXT_QUERY, "php")
329       .execute();
330     dbSession.clearCache();
331
332     // 2. Assert ActiveRule in DAO
333     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
334
335     // 1. Activate Rule with query returning 1 hits
336     wsActivateRules.newRequest().setMethod("POST")
337       .setParam(PARAM_TARGET_KEY, profile.getKee())
338       .setParam(Param.TEXT_QUERY, "world")
339       .execute();
340     dbSession.commit();
341
342     // 2. Assert ActiveRule in DAO
343     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(1);
344   }
345
346   @Test
347   public void bulk_activate_rule_by_query_with_severity() {
348     QProfileDto profile = createProfile("java");
349     RuleDefinitionDto rule0 = createRule(profile.getLanguage(), "toto");
350     RuleDefinitionDto rule1 = createRule(profile.getLanguage(), "tata");
351     dbSession.commit();
352
353     // 0. Assert No Active Rule for profile
354     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
355
356     // 2. Assert ActiveRule with BLOCKER severity
357     assertThat(ruleIndex.search(
358       new RuleQuery().setSeverities(ImmutableSet.of("BLOCKER")),
359       new SearchOptions()).getUuids()).hasSize(2);
360
361     // 1. Activate Rule with query returning 2 hits
362     wsActivateRules.newRequest().setMethod("POST")
363       .setParam(PARAM_TARGET_KEY, profile.getKee())
364       .setParam(PARAM_TARGET_SEVERITY, "MINOR")
365       .execute();
366     dbSession.commit();
367
368     // 2. Assert ActiveRule with MINOR severity
369     assertThat(dbClient.activeRuleDao().selectByOrgRuleUuid(dbSession, rule0.getUuid()).get(0).getSeverityString()).isEqualTo("MINOR");
370     assertThat(ruleIndex.searchAll(new RuleQuery()
371       .setQProfile(profile)
372       .setKey(rule0.getKey().toString())
373       .setActiveSeverities(Collections.singleton("MINOR"))
374       .setActivation(true))).toIterable().hasSize(1);
375   }
376
377   @Test
378   public void does_not_return_warnings_when_bulk_activate_on_profile_and_rules_exist_on_another_language_than_profile() {
379     QProfileDto javaProfile = createProfile("java");
380     createRule(javaProfile.getLanguage(), "toto");
381     createRule(javaProfile.getLanguage(), "tata");
382     QProfileDto phpProfile = createProfile("php");
383     createRule(phpProfile.getLanguage(), "hello");
384     createRule(phpProfile.getLanguage(), "world");
385     dbSession.commit();
386
387     // 1. Activate Rule
388     wsActivateRules.newRequest().setMethod("POST")
389       .setParam(PARAM_TARGET_KEY, javaProfile.getKee())
390       .setParam(PARAM_QPROFILE, javaProfile.getKee())
391       .setParam("activation", "false")
392       .execute()
393       .assertJson(getClass(), "does_not_return_warnings_when_bulk_activate_on_profile_and_rules_exist_on_another_language_than_profile.json");
394     dbSession.clearCache();
395
396     // 2. Assert ActiveRule in DAO
397     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, javaProfile.getKee())).hasSize(2);
398   }
399
400   @Test
401   public void reset() {
402     QProfileDto profile = QualityProfileTesting.newQualityProfileDto().setLanguage("java");
403     QProfileDto childProfile = QualityProfileTesting.newQualityProfileDto().setParentKee(profile.getKee()).setLanguage("java");
404     dbClient.qualityProfileDao().insert(dbSession, profile, childProfile);
405
406     RuleDefinitionDto rule = createRule(profile.getLanguage(), "rule");
407     ActiveRuleDto active1 = ActiveRuleDto.createFor(profile, rule)
408       .setSeverity(rule.getSeverityString());
409     ActiveRuleDto active2 = ActiveRuleDto.createFor(childProfile, rule)
410       .setSeverity("MINOR");
411     dbClient.activeRuleDao().insert(dbSession, active1);
412     dbClient.activeRuleDao().insert(dbSession, active2);
413
414     dbSession.commit();
415     activeRuleIndexer.indexAll();
416
417     // 0. assert rule child rule is minor
418     Optional<ActiveRuleDto> activeRuleDto = dbClient.activeRuleDao().selectByKey(dbSession, active2.getKey());
419     assertThat(activeRuleDto).isPresent();
420     assertThat(activeRuleDto.get().getSeverityString()).isEqualTo(Severity.MINOR);
421
422     // 1. reset child rule
423     wsActivateRule.newRequest().setMethod("POST")
424       .setParam(PARAM_KEY, childProfile.getKee())
425       .setParam(PARAM_RULE, rule.getKey().toString())
426       .setParam(PARAM_RESET, "true")
427       .execute();
428     dbSession.clearCache();
429
430     // 2. assert rule child rule is NOT minor
431     activeRuleDto = dbClient.activeRuleDao().selectByKey(dbSession, active2.getKey());
432     assertThat(activeRuleDto).isPresent();
433     assertThat(activeRuleDto.get().getSeverityString()).isNotEqualTo(Severity.MINOR);
434   }
435
436   private QProfileDto createProfile(String lang) {
437     QProfileDto profile = QualityProfileTesting.newQualityProfileDto().setName("P" + lang).setLanguage(lang);
438     dbClient.qualityProfileDao().insert(dbSession, profile);
439     return profile;
440   }
441
442   private RuleDefinitionDto createRule(String lang, String id) {
443     RuleDefinitionDto rule = RuleTesting.newRule(RuleKey.of("blah", id))
444       .setLanguage(lang)
445       .setSeverity(Severity.BLOCKER)
446       .setStatus(RuleStatus.READY);
447     dbClient.ruleDao().insert(dbSession, rule);
448     ruleIndexer.commitAndIndex(dbSession, rule.getUuid());
449     return rule;
450   }
451
452   private ActiveRuleDto createActiveRule(RuleDefinitionDto rule, QProfileDto profile) {
453     ActiveRuleDto activeRule = ActiveRuleDto.createFor(profile, rule)
454       .setSeverity(rule.getSeverityString());
455     dbClient.activeRuleDao().insert(dbSession, activeRule);
456     return activeRule;
457   }
458 }