]> source.dussan.org Git - sonarqube.git/blob
850a5dcdd1e98020ba9c4d2eb2f92a2e4fc3f431
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2021 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.ArrayList;
23 import java.util.List;
24 import org.junit.Rule;
25 import org.junit.Test;
26 import org.junit.rules.ExpectedException;
27 import org.sonar.api.resources.Language;
28 import org.sonar.api.resources.Languages;
29 import org.sonar.api.rule.RuleKey;
30 import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition;
31 import org.sonar.db.DbClient;
32 import org.sonar.db.DbTester;
33 import org.sonar.db.rule.RuleDefinitionDto;
34 import org.sonar.server.language.LanguageTesting;
35
36 import static java.util.Arrays.asList;
37 import static java.util.Collections.emptyList;
38 import static java.util.Collections.singletonList;
39 import static org.assertj.core.api.Assertions.assertThat;
40 import static org.assertj.core.groups.Tuple.tuple;
41 import static org.mockito.Mockito.mock;
42 import static org.sonar.db.rule.RuleTesting.EXTERNAL_XOO;
43 import static org.sonar.server.qualityprofile.BuiltInQProfile.ActiveRule;
44
45 public class BuiltInQProfileRepositoryImplTest {
46   private static final Language FOO_LANGUAGE = LanguageTesting.newLanguage("foo", "foo", "foo");
47   private static final String SONAR_WAY_QP_NAME = "Sonar way";
48
49   @Rule
50   public ExpectedException expectedException = ExpectedException.none();
51   @Rule
52   public DbTester db = DbTester.create();
53
54   private DbClient dbClient = db.getDbClient();
55
56   @Test
57   public void create_qprofile_with_rule() {
58     RuleDefinitionDto rule1 = db.rules().insert();
59     RuleDefinitionDto rule2 = db.rules().insert();
60     db.rules().insert();
61     List<DummyProfileDefinition> definitions = singletonList(new DummyProfileDefinition("foo", "foo", false,
62       asList(rule1.getKey(), rule2.getKey())));
63     BuiltInQProfileRepository underTest = new BuiltInQProfileRepositoryImpl(dbClient, new Languages(FOO_LANGUAGE), definitions.toArray(new BuiltInQualityProfilesDefinition[0]));
64
65     underTest.initialize();
66
67     assertThat(underTest.get())
68       .extracting(BuiltInQProfile::getName)
69       .containsExactlyInAnyOrder("foo");
70     assertThat(underTest.get().get(0).getActiveRules())
71       .extracting(ActiveRule::getRuleUuid, ActiveRule::getRuleKey)
72       .containsExactlyInAnyOrder(
73         tuple(rule1.getUuid(), rule1.getKey()),
74         tuple(rule2.getUuid(), rule2.getKey()));
75   }
76
77   @Test
78   public void make_single_profile_of_a_language_default_even_if_not_flagged_as_so() {
79     BuiltInQProfileRepository underTest = new BuiltInQProfileRepositoryImpl(dbClient, new Languages(FOO_LANGUAGE), new DummyProfileDefinition("foo", "foo1", false));
80
81     underTest.initialize();
82
83     assertThat(underTest.get())
84       .extracting(BuiltInQProfile::getLanguage, BuiltInQProfile::isDefault)
85       .containsExactly(tuple(FOO_LANGUAGE.getKey(), true));
86   }
87
88   @Test
89   public void make_single_profile_of_a_language_default_even_if_flagged_as_so() {
90     BuiltInQProfileRepository underTest = new BuiltInQProfileRepositoryImpl(dbClient, new Languages(FOO_LANGUAGE), new DummyProfileDefinition("foo", "foo1", true));
91
92     underTest.initialize();
93
94     assertThat(underTest.get())
95       .extracting(BuiltInQProfile::getLanguage, BuiltInQProfile::isDefault)
96       .containsExactly(tuple(FOO_LANGUAGE.getKey(), true));
97   }
98
99   @Test
100   public void make_first_profile_of_a_language_default_when_none_flagged_as_so() {
101     List<DummyProfileDefinition> definitions = new ArrayList<>(
102       asList(new DummyProfileDefinition("foo", "foo1", false), new DummyProfileDefinition("foo", "foo2", false)));
103     String firstName = definitions.get(0).getName();
104     String secondName = definitions.get(1).getName();
105     BuiltInQProfileRepository underTest = new BuiltInQProfileRepositoryImpl(dbClient, new Languages(FOO_LANGUAGE), definitions.toArray(new BuiltInQualityProfilesDefinition[0]));
106
107     underTest.initialize();
108
109     assertThat(underTest.get())
110       .extracting(BuiltInQProfile::getName, BuiltInQProfile::isDefault)
111       .containsExactlyInAnyOrder(tuple(firstName, true), tuple(secondName, false));
112   }
113
114   @Test
115   public void create_profile_Sonar_Way_as_default_if_none_other_is_defined_default_for_a_given_language() {
116     BuiltInQProfileRepository underTest = new BuiltInQProfileRepositoryImpl(
117       dbClient, new Languages(FOO_LANGUAGE),
118       new DummyProfileDefinition("foo", "doh", false), new DummyProfileDefinition("foo", "boo", false),
119       new DummyProfileDefinition("foo", SONAR_WAY_QP_NAME, false), new DummyProfileDefinition("foo", "goo", false));
120
121     underTest.initialize();
122
123     assertThat(underTest.get())
124       .filteredOn(b -> FOO_LANGUAGE.getKey().equals(b.getLanguage()))
125       .filteredOn(BuiltInQProfile::isDefault)
126       .extracting(BuiltInQProfile::getName)
127       .containsExactly(SONAR_WAY_QP_NAME);
128   }
129
130   @Test
131   public void do_not_create_Sonar_Way_as_default_if_other_profile_is_defined_as_default() {
132     BuiltInQProfileRepository underTest = new BuiltInQProfileRepositoryImpl(
133       dbClient, new Languages(FOO_LANGUAGE),
134       new DummyProfileDefinition("foo", SONAR_WAY_QP_NAME, false), new DummyProfileDefinition("foo", "goo", true));
135
136     underTest.initialize();
137
138     assertThat(underTest.get())
139       .filteredOn(b -> FOO_LANGUAGE.getKey().equals(b.getLanguage()))
140       .filteredOn(BuiltInQProfile::isDefault)
141       .extracting(BuiltInQProfile::getName)
142       .containsExactly("goo");
143   }
144
145   @Test
146   public void match_Sonar_Way_default_with_case_sensitivity() {
147     String sonarWayInOtherCase = SONAR_WAY_QP_NAME.toUpperCase();
148     BuiltInQProfileRepository underTest = new BuiltInQProfileRepositoryImpl(
149       dbClient, new Languages(FOO_LANGUAGE),
150       new DummyProfileDefinition("foo", "goo", false), new DummyProfileDefinition("foo", sonarWayInOtherCase, false));
151
152     underTest.initialize();
153
154     assertThat(underTest.get())
155       .filteredOn(b -> FOO_LANGUAGE.getKey().equals(b.getLanguage()))
156       .filteredOn(BuiltInQProfile::isDefault)
157       .extracting(BuiltInQProfile::getName)
158       .containsExactly("goo");
159   }
160
161   @Test
162   public void create_no_BuiltInQProfile_when_all_definitions_apply_to_non_defined_languages() {
163     BuiltInQProfileRepository underTest = new BuiltInQProfileRepositoryImpl(mock(DbClient.class), new Languages(), new DummyProfileDefinition("foo", "P1", false));
164
165     underTest.initialize();
166
167     assertThat(underTest.get()).isEmpty();
168   }
169
170   @Test
171   public void create_qprofile_with_deprecated_rule() {
172     RuleDefinitionDto rule1 = db.rules().insert();
173     db.rules().insertDeprecatedKey(d -> d.setRuleUuid(rule1.getUuid()).setOldRepositoryKey("oldRepo").setOldRuleKey("oldKey"));
174     RuleDefinitionDto rule2 = db.rules().insert();
175     List<DummyProfileDefinition> definitions = singletonList(new DummyProfileDefinition("foo", "foo", false,
176       asList(RuleKey.of("oldRepo", "oldKey"), rule2.getKey())));
177     BuiltInQProfileRepository underTest = new BuiltInQProfileRepositoryImpl(dbClient, new Languages(FOO_LANGUAGE), definitions.toArray(new BuiltInQualityProfilesDefinition[0]));
178
179     underTest.initialize();
180
181     assertThat(underTest.get())
182       .extracting(BuiltInQProfile::getName)
183       .containsExactlyInAnyOrder("foo");
184     assertThat(underTest.get().get(0).getActiveRules())
185       .extracting(ActiveRule::getRuleUuid, ActiveRule::getRuleKey)
186       .containsExactlyInAnyOrder(
187         tuple(rule1.getUuid(), rule1.getKey()),
188         tuple(rule2.getUuid(), rule2.getKey()));
189   }
190
191   @Test
192   public void fail_with_ISE_when_rule_does_not_exist() {
193     List<DummyProfileDefinition> definitions = singletonList(new DummyProfileDefinition("foo", "foo", false, singletonList(EXTERNAL_XOO)));
194     BuiltInQProfileRepository underTest = new BuiltInQProfileRepositoryImpl(dbClient, new Languages(FOO_LANGUAGE), definitions.toArray(new BuiltInQualityProfilesDefinition[0]));
195
196     expectedException.expect(IllegalStateException.class);
197     expectedException.expectMessage(String.format("Rule with key '%s' not found", EXTERNAL_XOO.toString()));
198
199     underTest.initialize();
200   }
201
202   @Test
203   public void fail_with_ISE_when_two_profiles_with_different_name_are_default_for_the_same_language() {
204     BuiltInQProfileRepository underTest = new BuiltInQProfileRepositoryImpl(dbClient, new Languages(FOO_LANGUAGE),
205       new DummyProfileDefinition("foo", "foo1", true), new DummyProfileDefinition("foo", "foo2", true));
206
207     expectedException.expect(IllegalStateException.class);
208     expectedException.expectMessage("Several Quality profiles are flagged as default for the language foo: [foo1, foo2]");
209
210     underTest.initialize();
211   }
212
213   @Test
214   public void get_throws_ISE_if_called_before_initialize() {
215     BuiltInQProfileRepositoryImpl underTest = new BuiltInQProfileRepositoryImpl(mock(DbClient.class), new Languages());
216
217     expectedException.expect(IllegalStateException.class);
218     expectedException.expectMessage("initialize must be called first");
219
220     underTest.get();
221   }
222
223   @Test
224   public void initialize_throws_ISE_if_called_twice() {
225     BuiltInQProfileRepositoryImpl underTest = new BuiltInQProfileRepositoryImpl(mock(DbClient.class), new Languages());
226     underTest.initialize();
227
228     expectedException.expect(IllegalStateException.class);
229     expectedException.expectMessage("initialize must be called only once");
230
231     underTest.initialize();
232   }
233
234   @Test
235   public void initialize_throws_ISE_if_language_has_no_builtin_qp() {
236     BuiltInQProfileRepository underTest = new BuiltInQProfileRepositoryImpl(mock(DbClient.class), new Languages(FOO_LANGUAGE));
237
238     expectedException.expect(IllegalStateException.class);
239     expectedException.expectMessage("The following languages have no built-in quality profiles: foo");
240
241     underTest.initialize();
242   }
243
244   private static final class DummyProfileDefinition implements BuiltInQualityProfilesDefinition {
245     private final String language;
246     private final String name;
247     private final boolean defaultProfile;
248     private final List<RuleKey> activeRuleKeys;
249
250     private DummyProfileDefinition(String language, String name, boolean defaultProfile, List<RuleKey> activeRuleKeys) {
251       this.language = language;
252       this.name = name;
253       this.defaultProfile = defaultProfile;
254       this.activeRuleKeys = activeRuleKeys;
255     }
256
257     private DummyProfileDefinition(String language, String name, boolean defaultProfile) {
258       this(language, name, defaultProfile, emptyList());
259     }
260
261     @Override
262     public void define(Context context) {
263       NewBuiltInQualityProfile builtInQualityProfile = context.createBuiltInQualityProfile(name, language);
264       activeRuleKeys.forEach(activeRuleKey -> builtInQualityProfile.activateRule(activeRuleKey.repository(), activeRuleKey.rule()));
265       builtInQualityProfile.setDefault(defaultProfile);
266       builtInQualityProfile.done();
267     }
268
269     String getName() {
270       return name;
271     }
272
273   }
274
275 }