]> source.dussan.org Git - sonarqube.git/blob
6a0642b003bed27f72c5c6dfd103327b252f976c
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2017 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;
21
22 import java.util.List;
23 import java.util.Optional;
24 import org.junit.Before;
25 import org.junit.Rule;
26 import org.junit.Test;
27 import org.sonar.api.profiles.RulesProfile;
28 import org.sonar.api.rules.RulePriority;
29 import org.sonar.api.utils.System2;
30 import org.sonar.api.utils.internal.TestSystem2;
31 import org.sonar.db.DbTester;
32 import org.sonar.db.qualityprofile.ActiveRuleDto;
33 import org.sonar.db.qualityprofile.RulesProfileDto;
34 import org.sonar.db.rule.RuleDefinitionDto;
35 import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
36 import org.sonar.server.tester.UserSessionRule;
37 import org.sonar.server.util.IntegerTypeValidation;
38 import org.sonar.server.util.StringTypeValidation;
39 import org.sonar.server.util.TypeValidations;
40
41 import static java.util.Arrays.asList;
42 import static org.assertj.core.api.Assertions.assertThat;
43 import static org.mockito.Mockito.mock;
44 import static org.sonar.api.rules.RulePriority.BLOCKER;
45 import static org.sonar.api.rules.RulePriority.CRITICAL;
46 import static org.sonar.api.rules.RulePriority.MAJOR;
47 import static org.sonar.db.qualityprofile.QualityProfileTesting.newRuleProfileDto;
48
49 public class BuiltInQProfileUpdateImplTest {
50
51   private static final long NOW = 1_000;
52   private static final long PAST = NOW - 100;
53
54   @Rule
55   public BuiltInQProfileRepositoryRule builtInProfileRepository = new BuiltInQProfileRepositoryRule();
56   @Rule
57   public DbTester db = DbTester.create().setDisableDefaultOrganization(true);
58   @Rule
59   public UserSessionRule userSession = UserSessionRule.standalone();
60   private System2 system2 = new TestSystem2().setNow(NOW);
61   private ActiveRuleIndexer activeRuleIndexer = mock(ActiveRuleIndexer.class);
62   private RuleActivatorContextFactory contextFactory = new RuleActivatorContextFactory(db.getDbClient());
63   private TypeValidations typeValidations = new TypeValidations(asList(new StringTypeValidation(), new IntegerTypeValidation()));
64   private RuleActivator ruleActivator = new RuleActivator(system2, db.getDbClient(), null, contextFactory, typeValidations, activeRuleIndexer, userSession);
65
66   private BuiltInQProfileUpdateImpl underTest = new BuiltInQProfileUpdateImpl(db.getDbClient(), ruleActivator, activeRuleIndexer);
67
68   private RulesProfileDto persistedProfile;
69
70   @Before
71   public void setUp() {
72     persistedProfile = newRuleProfileDto(rp -> rp
73       .setIsBuiltIn(true)
74       .setLanguage("xoo")
75       .setRulesUpdatedAt(null));
76     db.getDbClient().qualityProfileDao().insert(db.getSession(), persistedProfile);
77     db.commit();
78   }
79
80   @Test
81   public void activate_new_rules() {
82     RuleDefinitionDto rule1 = db.rules().insert(r -> r.setLanguage("xoo"));
83     RuleDefinitionDto rule2 = db.rules().insert(r -> r.setLanguage("xoo"));
84     RulesProfile apiProfile = RulesProfile.create("Sonar way", "xoo");
85     activateRuleInDef(apiProfile, rule1, CRITICAL);
86     activateRuleInDef(apiProfile, rule2, MAJOR);
87     BuiltInQProfile builtIn = builtInProfileRepository.create(apiProfile);
88
89     underTest.update(db.getSession(), builtIn, persistedProfile);
90
91     List<ActiveRuleDto> activeRules = db.getDbClient().activeRuleDao().selectByRuleProfile(db.getSession(), persistedProfile);
92     assertThat(activeRules).hasSize(2);
93     assertThatRuleIsNewlyActivated(activeRules, rule1, CRITICAL);
94     assertThatRuleIsNewlyActivated(activeRules, rule2, MAJOR);
95     assertThatProfileIsMarkedAsUpdated(persistedProfile);
96   }
97
98   @Test
99   public void already_activated_rule_is_updated_in_case_of_differences() {
100     RuleDefinitionDto rule = db.rules().insert(r -> r.setLanguage("xoo"));
101     RulesProfile apiProfile = RulesProfile.create("Sonar way", "xoo");
102     activateRuleInDef(apiProfile, rule, CRITICAL);
103     BuiltInQProfile builtIn = builtInProfileRepository.create(apiProfile);
104
105     activateRuleInDb(persistedProfile, rule, BLOCKER);
106
107     underTest.update(db.getSession(), builtIn, persistedProfile);
108
109     List<ActiveRuleDto> activeRules = db.getDbClient().activeRuleDao().selectByRuleProfile(db.getSession(), persistedProfile);
110     assertThat(activeRules).hasSize(1);
111     assertThatRuleIsUpdated(activeRules, rule, CRITICAL);
112     assertThatProfileIsMarkedAsUpdated(persistedProfile);
113   }
114
115   @Test
116   public void already_activated_rule_is_not_touched_if_no_differences() {
117     RuleDefinitionDto rule = db.rules().insert(r -> r.setLanguage("xoo"));
118     RulesProfile apiProfile = RulesProfile.create("Sonar way", "xoo");
119     activateRuleInDef(apiProfile, rule, CRITICAL);
120     BuiltInQProfile builtIn = builtInProfileRepository.create(apiProfile);
121
122     activateRuleInDb(persistedProfile, rule, CRITICAL);
123
124     underTest.update(db.getSession(), builtIn, persistedProfile);
125
126     List<ActiveRuleDto> activeRules = db.getDbClient().activeRuleDao().selectByRuleProfile(db.getSession(), persistedProfile);
127     assertThat(activeRules).hasSize(1);
128     assertThatRuleIsUntouched(activeRules, rule, CRITICAL);
129     assertThatProfileIsNotMarkedAsUpdated(persistedProfile);
130   }
131
132   @Test
133   public void deactivate_rule_that_is_not_in_built_in_definition_anymore() {
134     RuleDefinitionDto rule1 = db.rules().insert(r -> r.setLanguage("xoo"));
135     RuleDefinitionDto rule2 = db.rules().insert(r -> r.setLanguage("xoo"));
136     RulesProfile apiProfile = RulesProfile.create("Sonar way", "xoo");
137     activateRuleInDef(apiProfile, rule2, CRITICAL);
138     BuiltInQProfile builtIn = builtInProfileRepository.create(apiProfile);
139
140     // built-in definition contains only rule2
141     // so rule1 must be deactivated
142     activateRuleInDb(persistedProfile, rule1, CRITICAL);
143
144     underTest.update(db.getSession(), builtIn, persistedProfile);
145
146     List<ActiveRuleDto> activeRules = db.getDbClient().activeRuleDao().selectByRuleProfile(db.getSession(), persistedProfile);
147     assertThat(activeRules).hasSize(1);
148     assertThatRuleIsDeactivated(activeRules, rule1);
149     assertThatProfileIsMarkedAsUpdated(persistedProfile);
150   }
151
152   @Test
153   public void activate_deactivate_and_update_three_rules_at_the_same_time() {
154     RuleDefinitionDto rule1 = db.rules().insert(r -> r.setLanguage("xoo"));
155     RuleDefinitionDto rule2 = db.rules().insert(r -> r.setLanguage("xoo"));
156     RuleDefinitionDto rule3 = db.rules().insert(r -> r.setLanguage("xoo"));
157     RulesProfile apiProfile = RulesProfile.create("Sonar way", "xoo");
158     activateRuleInDef(apiProfile, rule1, CRITICAL);
159     activateRuleInDef(apiProfile, rule2, MAJOR);
160     BuiltInQProfile builtIn = builtInProfileRepository.create(apiProfile);
161
162     // rule1 must be updated (blocker to critical)
163     // rule2 must be activated
164     // rule3 must be deactivated
165     activateRuleInDb(persistedProfile, rule1, BLOCKER);
166     activateRuleInDb(persistedProfile, rule3, BLOCKER);
167
168     underTest.update(db.getSession(), builtIn, persistedProfile);
169
170     List<ActiveRuleDto> activeRules = db.getDbClient().activeRuleDao().selectByRuleProfile(db.getSession(), persistedProfile);
171     assertThat(activeRules).hasSize(2);
172     assertThatRuleIsUpdated(activeRules, rule1, CRITICAL);
173     assertThatRuleIsNewlyActivated(activeRules, rule2, MAJOR);
174     assertThatRuleIsDeactivated(activeRules, rule3);
175     assertThatProfileIsMarkedAsUpdated(persistedProfile);
176   }
177
178
179   private static void assertThatRuleIsNewlyActivated(List<ActiveRuleDto> activeRules, RuleDefinitionDto rule, RulePriority severity) {
180     ActiveRuleDto activeRule = findRule(activeRules, rule).get();
181
182     assertThat(activeRule.getInheritance()).isNull();
183     assertThat(activeRule.getSeverityString()).isEqualTo(severity.name());
184     assertThat(activeRule.getCreatedAt()).isEqualTo(NOW);
185     assertThat(activeRule.getUpdatedAt()).isEqualTo(NOW);
186   }
187
188   private static void assertThatRuleIsUpdated(List<ActiveRuleDto> activeRules, RuleDefinitionDto rule, RulePriority severity) {
189     ActiveRuleDto activeRule = findRule(activeRules, rule).get();
190
191     assertThat(activeRule.getInheritance()).isNull();
192     assertThat(activeRule.getSeverityString()).isEqualTo(severity.name());
193     assertThat(activeRule.getCreatedAt()).isEqualTo(PAST);
194     assertThat(activeRule.getUpdatedAt()).isEqualTo(NOW);
195   }
196
197   private static void assertThatRuleIsUntouched(List<ActiveRuleDto> activeRules, RuleDefinitionDto rule, RulePriority severity) {
198     ActiveRuleDto activeRule = findRule(activeRules, rule).get();
199
200     assertThat(activeRule.getInheritance()).isNull();
201     assertThat(activeRule.getSeverityString()).isEqualTo(severity.name());
202     assertThat(activeRule.getCreatedAt()).isEqualTo(PAST);
203     assertThat(activeRule.getUpdatedAt()).isEqualTo(PAST);
204   }
205
206   private static void assertThatRuleIsDeactivated(List<ActiveRuleDto> activeRules, RuleDefinitionDto rule) {
207     assertThat(findRule(activeRules, rule)).isEmpty();
208   }
209
210   private void assertThatProfileIsMarkedAsUpdated(RulesProfileDto dto) {
211     RulesProfileDto reloaded = db.getDbClient().qualityProfileDao().selectBuiltInRulesProfiles(db.getSession())
212       .stream()
213       .filter(p -> p.getKee().equals(dto.getKee()))
214       .findFirst()
215       .get();
216     assertThat(reloaded.getRulesUpdatedAt()).isNotEmpty();
217   }
218
219   private void assertThatProfileIsNotMarkedAsUpdated(RulesProfileDto dto) {
220     RulesProfileDto reloaded = db.getDbClient().qualityProfileDao().selectBuiltInRulesProfiles(db.getSession())
221       .stream()
222       .filter(p -> p.getKee().equals(dto.getKee()))
223       .findFirst()
224       .get();
225     assertThat(reloaded.getRulesUpdatedAt()).isNull();
226   }
227
228   private static Optional<ActiveRuleDto> findRule(List<ActiveRuleDto> activeRules, RuleDefinitionDto rule) {
229     return activeRules.stream()
230       .filter(ar -> ar.getRuleKey().equals(rule.getKey()))
231       .findFirst();
232   }
233
234   private static void activateRuleInDef(RulesProfile apiProfile, RuleDefinitionDto rule, RulePriority severity) {
235     apiProfile.activateRule(org.sonar.api.rules.Rule.create(rule.getRepositoryKey(), rule.getRuleKey()), severity);
236   }
237
238   private void activateRuleInDb(RulesProfileDto profile, RuleDefinitionDto rule, RulePriority severity) {
239     ActiveRuleDto dto = new ActiveRuleDto()
240       .setProfileId(profile.getId())
241       .setSeverity(severity.name())
242       .setRuleId(rule.getId())
243       .setCreatedAt(PAST)
244       .setUpdatedAt(PAST);
245     db.getDbClient().activeRuleDao().insert(db.getSession(), dto);
246     db.commit();
247   }
248
249 }