3 * Copyright (C) 2009-2024 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.builtin;
22 import java.util.Arrays;
23 import java.util.List;
24 import org.junit.After;
25 import org.junit.Rule;
26 import org.junit.Test;
27 import org.sonar.api.PropertyType;
28 import org.sonar.api.impl.utils.AlwaysIncreasingSystem2;
29 import org.sonar.api.rule.Severity;
30 import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition;
31 import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition.NewBuiltInQualityProfile;
32 import org.sonar.api.utils.System2;
33 import org.sonar.api.utils.Version;
34 import org.sonar.core.platform.SonarQubeVersion;
35 import org.sonar.core.util.SequenceUuidFactory;
36 import org.sonar.core.util.UuidFactory;
37 import org.sonar.db.DbSession;
38 import org.sonar.db.DbTester;
39 import org.sonar.db.qualityprofile.ActiveRuleDto;
40 import org.sonar.db.qualityprofile.ActiveRuleKey;
41 import org.sonar.db.qualityprofile.ActiveRuleParamDto;
42 import org.sonar.db.qualityprofile.QProfileChangeDto;
43 import org.sonar.db.qualityprofile.QProfileChangeQuery;
44 import org.sonar.db.qualityprofile.QProfileDto;
45 import org.sonar.db.rule.RuleDto;
46 import org.sonar.db.rule.RuleParamDto;
47 import org.sonar.server.qualityprofile.ActiveRuleChange;
48 import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
49 import org.sonar.server.rule.DefaultRuleFinder;
50 import org.sonar.server.rule.RuleDescriptionFormatter;
51 import org.sonar.server.rule.ServerRuleFinder;
52 import org.sonar.server.util.StringTypeValidation;
53 import org.sonar.server.util.TypeValidations;
55 import static java.util.Collections.singletonList;
56 import static org.assertj.core.api.Assertions.assertThat;
57 import static org.mockito.Mockito.mock;
59 public class BuiltInQProfileInsertImplIT {
62 public BuiltInQProfileRepositoryRule builtInQProfileRepository = new BuiltInQProfileRepositoryRule();
64 public DbTester db = DbTester.create();
66 private final System2 system2 = new AlwaysIncreasingSystem2();
67 private final UuidFactory uuidFactory = new SequenceUuidFactory();
68 private final TypeValidations typeValidations = new TypeValidations(singletonList(new StringTypeValidation()));
69 private final DbSession dbSession = db.getSession();
70 private final DbSession batchDbSession = db.getDbClient().openSession(true);
71 private final ServerRuleFinder ruleFinder = new DefaultRuleFinder(db.getDbClient(), mock(RuleDescriptionFormatter.class));
72 private final ActiveRuleIndexer activeRuleIndexer = mock(ActiveRuleIndexer.class);
73 private final SonarQubeVersion sonarQubeVersion = new SonarQubeVersion(Version.create(10, 3));
74 private final BuiltInQProfileInsertImpl underTest = new BuiltInQProfileInsertImpl(db.getDbClient(), ruleFinder, system2, uuidFactory, typeValidations, activeRuleIndexer, sonarQubeVersion);
77 public void tearDown() {
78 batchDbSession.close();
82 public void insert_active_rules_and_changelog() {
83 RuleDto rule1 = db.rules().insert(r -> r.setLanguage("xoo"));
84 RuleDto rule2 = db.rules().insert(r -> r.setLanguage("xoo"));
86 BuiltInQualityProfilesDefinition.Context context = new BuiltInQualityProfilesDefinition.Context();
87 NewBuiltInQualityProfile newQp = context.createBuiltInQualityProfile("the name", "xoo");
89 newQp.activateRule(rule1.getRepositoryKey(), rule1.getRuleKey()).overrideSeverity(Severity.CRITICAL);
90 newQp.activateRule(rule2.getRepositoryKey(), rule2.getRuleKey()).overrideSeverity(Severity.MAJOR);
93 BuiltInQProfile builtIn = builtInQProfileRepository.create(context.profile("xoo", "the name"), rule1, rule2);
96 verifyTableSize("rules_profiles", 1);
97 verifyTableSize("org_qprofiles", 1);
98 verifyTableSize("active_rules", 2);
99 verifyTableSize("active_rule_parameters", 0);
100 verifyTableSize("qprofile_changes", 2);
101 verifyTableSize("default_qprofiles", 0);
103 QProfileDto profile = verifyProfileInDb(builtIn);
104 verifyActiveRuleInDb(profile, rule1, Severity.CRITICAL);
105 verifyActiveRuleInDb(profile, rule2, Severity.MAJOR);
109 public void insert_default_qp() {
110 BuiltInQualityProfilesDefinition.Context context = new BuiltInQualityProfilesDefinition.Context();
111 context.createBuiltInQualityProfile("the name", "xoo")
115 BuiltInQProfile builtIn = builtInQProfileRepository.create(context.profile("xoo", "the name"));
118 verifyTableSize("rules_profiles", 1);
119 verifyTableSize("org_qprofiles", 1);
120 verifyTableSize("active_rules", 0);
121 verifyTableSize("active_rule_parameters", 0);
122 verifyTableSize("qprofile_changes", 0);
123 verifyTableSize("default_qprofiles", 1);
125 verifyProfileInDb(builtIn);
129 public void insert_active_rules_with_params() {
130 RuleDto rule1 = db.rules().insert(r -> r.setLanguage("xoo"));
131 RuleParamDto param1 = db.rules().insertRuleParam(rule1, p -> p.setType(PropertyType.STRING.name()));
132 RuleParamDto param2 = db.rules().insertRuleParam(rule1, p -> p.setType(PropertyType.STRING.name()));
134 BuiltInQualityProfilesDefinition.Context context = new BuiltInQualityProfilesDefinition.Context();
135 NewBuiltInQualityProfile newQp = context.createBuiltInQualityProfile("the name", "xoo");
137 newQp.activateRule(rule1.getRepositoryKey(), rule1.getRuleKey()).overrideSeverity(Severity.CRITICAL);
140 BuiltInQProfile builtIn = builtInQProfileRepository.create(context.profile("xoo", "the name"), rule1);
143 verifyTableSize("rules_profiles", 1);
144 verifyTableSize("org_qprofiles", 1);
145 verifyTableSize("active_rules", 1);
146 verifyTableSize("active_rule_parameters", 2);
147 verifyTableSize("qprofile_changes", 1);
149 QProfileDto profile = verifyProfileInDb(builtIn);
150 verifyActiveRuleInDb(profile, rule1, Severity.CRITICAL, param1, param2);
154 public void flag_profile_as_default_if_declared_as_default_by_api() {
155 BuiltInQualityProfilesDefinition.Context context = new BuiltInQualityProfilesDefinition.Context();
156 NewBuiltInQualityProfile newQp = context.createBuiltInQualityProfile("the name", "xoo").setDefault(true);
159 BuiltInQProfile builtIn = builtInQProfileRepository.create(context.profile("xoo", "the name"));
163 QProfileDto profile = verifyProfileInDb(builtIn);
164 QProfileDto defaultProfile = db.getDbClient().qualityProfileDao().selectDefaultProfile(dbSession, "xoo");
165 assertThat(defaultProfile.getKee()).isEqualTo(profile.getKee());
169 public void existing_default_profile_must_not_be_changed() {
170 BuiltInQualityProfilesDefinition.Context context = new BuiltInQualityProfilesDefinition.Context();
171 NewBuiltInQualityProfile newQp = context.createBuiltInQualityProfile("the name", "xoo").setDefault(true);
173 BuiltInQProfile builtIn = builtInQProfileRepository.create(context.profile("xoo", "the name"));
175 QProfileDto currentDefault = db.qualityProfiles().insert(p -> p.setLanguage("xoo"));
176 db.qualityProfiles().setAsDefault(currentDefault);
180 QProfileDto defaultProfile = db.getDbClient().qualityProfileDao().selectDefaultProfile(dbSession, "xoo");
181 assertThat(defaultProfile.getKee()).isEqualTo(currentDefault.getKee());
182 verifyTableSize("rules_profiles", 2);
186 public void dont_flag_profile_as_default_if_not_declared_as_default_by_api() {
187 BuiltInQualityProfilesDefinition.Context context = new BuiltInQualityProfilesDefinition.Context();
188 NewBuiltInQualityProfile newQp = context.createBuiltInQualityProfile("the name", "xoo").setDefault(false);
190 BuiltInQProfile builtIn = builtInQProfileRepository.create(context.profile("xoo", "the name"));
194 QProfileDto defaultProfile = db.getDbClient().qualityProfileDao().selectDefaultProfile(dbSession, "xoo");
195 assertThat(defaultProfile).isNull();
198 // TODO test lot of active_rules, params, orgas
200 private void verifyActiveRuleInDb(QProfileDto profile, RuleDto rule, String expectedSeverity, RuleParamDto... paramDtos) {
201 ActiveRuleDto activeRule = db.getDbClient().activeRuleDao().selectByKey(dbSession, ActiveRuleKey.of(profile, rule.getKey())).get();
202 assertThat(activeRule.getUuid()).isNotNull();
203 assertThat(activeRule.getInheritance()).isNull();
204 assertThat(activeRule.doesOverride()).isFalse();
205 assertThat(activeRule.getRuleUuid()).isEqualTo(rule.getUuid());
206 assertThat(activeRule.getProfileUuid()).isEqualTo(profile.getRulesProfileUuid());
207 assertThat(activeRule.getSeverityString()).isEqualTo(expectedSeverity);
208 assertThat(activeRule.getCreatedAt()).isPositive();
209 assertThat(activeRule.getUpdatedAt()).isPositive();
211 List<ActiveRuleParamDto> params = db.getDbClient().activeRuleDao().selectParamsByActiveRuleUuid(dbSession, activeRule.getUuid());
212 assertThat(params).extracting(ActiveRuleParamDto::getKey).containsOnly(Arrays.stream(paramDtos).map(RuleParamDto::getName).toArray(String[]::new));
214 QProfileChangeQuery changeQuery = new QProfileChangeQuery(profile.getKee());
215 QProfileChangeDto change = db.getDbClient().qProfileChangeDao().selectByQuery(dbSession, changeQuery).stream()
216 .filter(c -> c.getDataAsMap().get("ruleUuid").equals(rule.getUuid()))
219 assertThat(change.getChangeType()).isEqualTo(ActiveRuleChange.Type.ACTIVATED.name());
220 assertThat(change.getCreatedAt()).isPositive();
221 assertThat(change.getUuid()).isNotEmpty();
222 assertThat(change.getUserUuid()).isNull();
223 assertThat(change.getRulesProfileUuid()).isEqualTo(profile.getRulesProfileUuid());
224 assertThat(change.getDataAsMap()).containsEntry("severity", expectedSeverity);
225 assertThat(change.getSqVersion()).isEqualTo(sonarQubeVersion.toString());
228 private QProfileDto verifyProfileInDb(BuiltInQProfile builtIn) {
229 QProfileDto profileOnOrg1 = db.getDbClient().qualityProfileDao().selectByNameAndLanguage(dbSession, builtIn.getName(), builtIn.getLanguage());
230 assertThat(profileOnOrg1.getLanguage()).isEqualTo(builtIn.getLanguage());
231 assertThat(profileOnOrg1.getName()).isEqualTo(builtIn.getName());
232 assertThat(profileOnOrg1.getParentKee()).isNull();
233 assertThat(profileOnOrg1.getLastUsed()).isNull();
234 assertThat(profileOnOrg1.getUserUpdatedAt()).isNull();
235 assertThat(profileOnOrg1.getRulesUpdatedAt()).isNotEmpty();
236 assertThat(profileOnOrg1.getKee()).isNotEqualTo(profileOnOrg1.getRulesProfileUuid());
237 assertThat(profileOnOrg1.getRulesProfileUuid()).isNotNull();
238 return profileOnOrg1;
241 private void verifyTableSize(String table, int expectedSize) {
242 assertThat(db.countRowsOfTable(dbSession, table)).as("table " + table).isEqualTo(expectedSize);
245 private void call(BuiltInQProfile builtIn) {
246 underTest.create(dbSession, builtIn);
248 batchDbSession.commit();