]> source.dussan.org Git - sonarqube.git/blob
31658beb136cf95fcf2dd5ad510c9232c127e736
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2020 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.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;
60
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;
72
73 public class QProfilesWsMediumTest {
74
75   @Rule
76   public UserSessionRule userSessionRule = UserSessionRule.standalone()
77     .logIn().setRoot();
78   @Rule
79   public EsTester es = EsTester.create();
80   @Rule
81   public DbTester dbTester = DbTester.create();
82
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;
95
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));
100
101   @Before
102   public void setUp() {
103     organization = dbTester.organizations().insert();
104   }
105
106   @Test
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());
113
114     // 0. Assert No Active Rule for profile
115     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(1);
116
117     // 1. Deactivate Rule
118     wsDeactivateRule.newRequest().setMethod("POST")
119       .setParam(PARAM_KEY, profile.getKee())
120       .setParam(PARAM_RULE, rule.getKey().toString())
121       .execute();
122     dbSession.clearCache();
123
124     // 2. Assert ActiveRule in DAO
125     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
126   }
127
128   @Test
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);
139     dbSession.commit();
140     activeRuleIndexer.indexOnStartup(activeRuleIndexer.getIndexTypes());
141
142     // 0. Assert No Active Rule for profile
143     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(4);
144
145     // 1. Deactivate Rule
146     wsDeactivateRules.newRequest().setMethod("POST")
147       .setParam(PARAM_TARGET_KEY, profile.getKee())
148       .execute();
149     dbSession.clearCache();
150
151     // 2. Assert ActiveRule in DAO
152     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
153   }
154
155   @Test
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);
165     dbSession.commit();
166     activeRuleIndexer.indexOnStartup(activeRuleIndexer.getIndexTypes());
167
168     // 0. Assert No Active Rule for profile
169     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(2);
170
171     // 1. Deactivate Rule
172     wsDeactivateRules.newRequest().setMethod("POST")
173       .setParam(PARAM_TARGET_KEY, profile.getKee())
174       .execute();
175     dbSession.clearCache();
176
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);
180   }
181
182   @Test
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);
189     dbSession.commit();
190     activeRuleIndexer.indexOnStartup(activeRuleIndexer.getIndexTypes());
191
192     // 0. Assert No Active Rule for profile
193     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(2);
194
195     // 1. Deactivate Rule
196     wsDeactivateRules.newRequest().setMethod("POST")
197       .setParam(PARAM_TARGET_KEY, profile.getKee())
198       .setParam(Param.TEXT_QUERY, "hello")
199       .execute();
200     dbSession.clearCache();
201
202     // 2. Assert ActiveRule in DAO
203     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(1);
204   }
205
206   @Test
207   public void activate_rule() {
208     QProfileDto profile = createProfile("java");
209     RuleDefinitionDto rule = createRule(profile.getLanguage(), "toto");
210     ruleIndexer.commitAndIndex(dbSession, rule.getUuid());
211
212     // 0. Assert No Active Rule for profile
213     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
214
215     // 1. Activate Rule
216     wsActivateRule.newRequest().setMethod("POST")
217       .setParam(PARAM_KEY, profile.getKee())
218       .setParam(PARAM_RULE, rule.getKey().toString())
219       .execute();
220     dbSession.clearCache();
221
222     // 2. Assert ActiveRule in DAO
223     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(1);
224   }
225
226   @Test
227   public void activate_rule_diff_languages() {
228     QProfileDto profile = createProfile("java");
229     RuleDefinitionDto rule = createRule("php", "toto");
230     ruleIndexer.commitAndIndex(dbSession, rule.getUuid());
231
232     // 0. Assert No Active Rule for profile
233     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
234
235     try {
236       // 1. Activate Rule
237       wsActivateRule.newRequest().setMethod("POST")
238         .setParam(PARAM_KEY, profile.getKee())
239         .setParam(PARAM_RULE, rule.getKey().toString())
240         .execute();
241       dbSession.clearCache();
242       fail();
243     } catch (BadRequestException e) {
244       assertThat(e.getMessage()).isEqualTo("php rule blah:toto cannot be activated on java profile Pjava");
245     }
246   }
247
248   @Test
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());
253
254     // 0. Assert No Active Rule for profile
255     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
256
257     // 1. Activate Rule
258     wsActivateRule.newRequest().setMethod("POST")
259       .setParam(PARAM_KEY, profile.getKee())
260       .setParam(PARAM_RULE, rule.getKey().toString())
261       .setParam(PARAM_SEVERITY, "MINOR")
262       .execute();
263     dbSession.clearCache();
264
265     // 2. Assert ActiveRule in DAO
266     ActiveRuleKey activeRuleKey = ActiveRuleKey.of(profile, rule.getKey());
267
268     Optional<ActiveRuleDto> activeRuleDto = dbClient.activeRuleDao().selectByKey(dbSession, activeRuleKey);
269     assertThat(activeRuleDto.isPresent()).isTrue();
270     assertThat(activeRuleDto.get().getSeverityString()).isEqualTo(Severity.MINOR);
271   }
272
273   @Test
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");
280     dbSession.commit();
281
282     // 0. Assert No Active Rule for profile
283     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
284
285     // 1. Activate Rule
286     wsActivateRules.newRequest().setMethod("POST")
287       .setParam(PARAM_TARGET_KEY, profile.getKee())
288       .setParam(PARAM_LANGUAGES, "java")
289       .execute()
290       .assertJson(getClass(), "bulk_activate_rule.json");
291     dbSession.clearCache();
292
293     // 2. Assert ActiveRule in DAO
294     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(4);
295   }
296
297   @Test
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");
305     dbSession.commit();
306
307     // 0. Assert No Active Rule for profile
308     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, php.getKee())).isEmpty();
309
310     // 1. Activate Rule
311     wsActivateRules.newRequest().setMethod("POST")
312       .setParam(PARAM_TARGET_KEY, php.getKee())
313       .setParam(PARAM_LANGUAGES, "php")
314       .execute()
315       .assertJson(getClass(), "bulk_activate_rule_not_all.json");
316     dbSession.clearCache();
317
318     // 2. Assert ActiveRule in DAO
319     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, php.getKee())).hasSize(2);
320   }
321
322   @Test
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");
329     dbSession.commit();
330
331     // 0. Assert No Active Rule for profile
332     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
333
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")
338       .execute();
339     dbSession.clearCache();
340
341     // 2. Assert ActiveRule in DAO
342     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(0);
343
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")
348       .execute();
349     dbSession.commit();
350
351     // 2. Assert ActiveRule in DAO
352     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(1);
353   }
354
355   @Test
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");
360     dbSession.commit();
361
362     // 0. Assert No Active Rule for profile
363     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
364
365     // 2. Assert ActiveRule with BLOCKER severity
366     assertThat(ruleIndex.search(
367       new RuleQuery().setSeverities(ImmutableSet.of("BLOCKER")),
368       new SearchOptions()).getUuids()).hasSize(2);
369
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")
374       .execute();
375     dbSession.commit();
376
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);
384   }
385
386   @Test
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");
394     dbSession.commit();
395
396     // 1. Activate Rule
397     wsActivateRules.newRequest().setMethod("POST")
398       .setParam(PARAM_TARGET_KEY, javaProfile.getKee())
399       .setParam(PARAM_QPROFILE, javaProfile.getKee())
400       .setParam("activation", "false")
401       .execute()
402       .assertJson(getClass(), "does_not_return_warnings_when_bulk_activate_on_profile_and_rules_exist_on_another_language_than_profile.json");
403     dbSession.clearCache();
404
405     // 2. Assert ActiveRule in DAO
406     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, javaProfile.getKee())).hasSize(2);
407   }
408
409   @Test
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);
414
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);
422
423     dbSession.commit();
424     activeRuleIndexer.indexOnStartup(activeRuleIndexer.getIndexTypes());
425
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);
430
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")
436       .execute();
437     dbSession.clearCache();
438
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);
443   }
444
445   private QProfileDto createProfile(String lang) {
446     QProfileDto profile = QProfileTesting.newQProfileDto(new QProfileName(lang, "P" + lang), "p" + lang);
447     dbClient.qualityProfileDao().insert(dbSession, profile);
448     return profile;
449   }
450
451   private RuleDefinitionDto createRule(String lang, String id) {
452     RuleDefinitionDto rule = RuleTesting.newRule(RuleKey.of("blah", id))
453       .setLanguage(lang)
454       .setSeverity(Severity.BLOCKER)
455       .setStatus(RuleStatus.READY);
456     dbClient.ruleDao().insert(dbSession, rule);
457     ruleIndexer.commitAndIndex(dbSession, rule.getUuid());
458     return rule;
459   }
460
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);
465     return activeRule;
466   }
467 }