You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

QProfileRuleImplTest.java 44KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2019 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. import java.util.ArrayList;
  22. import java.util.List;
  23. import java.util.Map;
  24. import java.util.Optional;
  25. import java.util.Random;
  26. import java.util.stream.IntStream;
  27. import javax.annotation.Nullable;
  28. import org.junit.Rule;
  29. import org.junit.Test;
  30. import org.junit.rules.ExpectedException;
  31. import org.sonar.api.PropertyType;
  32. import org.sonar.api.rule.RuleStatus;
  33. import org.sonar.api.rule.Severity;
  34. import org.sonar.api.utils.System2;
  35. import org.sonar.api.utils.internal.AlwaysIncreasingSystem2;
  36. import org.sonar.db.DbTester;
  37. import org.sonar.db.qualityprofile.ActiveRuleParamDto;
  38. import org.sonar.db.qualityprofile.OrgActiveRuleDto;
  39. import org.sonar.db.qualityprofile.QProfileDto;
  40. import org.sonar.db.rule.RuleDefinitionDto;
  41. import org.sonar.db.rule.RuleDto;
  42. import org.sonar.db.rule.RuleParamDto;
  43. import org.sonar.server.es.EsTester;
  44. import org.sonar.server.es.SearchOptions;
  45. import org.sonar.server.exceptions.BadRequestException;
  46. import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
  47. import org.sonar.server.rule.index.RuleIndex;
  48. import org.sonar.server.rule.index.RuleIndexer;
  49. import org.sonar.server.rule.index.RuleQuery;
  50. import org.sonar.server.tester.UserSessionRule;
  51. import org.sonar.server.util.IntegerTypeValidation;
  52. import org.sonar.server.util.StringTypeValidation;
  53. import org.sonar.server.util.TypeValidations;
  54. import static com.google.common.collect.ImmutableMap.of;
  55. import static java.util.Arrays.asList;
  56. import static java.util.Collections.emptyMap;
  57. import static java.util.Collections.singleton;
  58. import static java.util.Collections.singletonList;
  59. import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
  60. import static org.assertj.core.api.Assertions.assertThat;
  61. import static org.junit.Assert.fail;
  62. import static org.sonar.api.rule.Severity.BLOCKER;
  63. import static org.sonar.api.rule.Severity.CRITICAL;
  64. import static org.sonar.api.rule.Severity.MAJOR;
  65. import static org.sonar.api.rule.Severity.MINOR;
  66. import static org.sonar.db.rule.RuleTesting.newCustomRule;
  67. import static org.sonar.server.qualityprofile.ActiveRuleInheritance.INHERITED;
  68. public class QProfileRuleImplTest {
  69. @Rule
  70. public ExpectedException expectedException = ExpectedException.none();
  71. private System2 system2 = new AlwaysIncreasingSystem2();
  72. @Rule
  73. public DbTester db = DbTester.create(system2);
  74. @Rule
  75. public EsTester es = EsTester.create();
  76. @Rule
  77. public UserSessionRule userSession = UserSessionRule.standalone();
  78. private RuleIndex ruleIndex = new RuleIndex(es.client(), system2);
  79. private ActiveRuleIndexer activeRuleIndexer = new ActiveRuleIndexer(db.getDbClient(), es.client());
  80. private RuleIndexer ruleIndexer = new RuleIndexer(es.client(), db.getDbClient());
  81. private TypeValidations typeValidations = new TypeValidations(asList(new StringTypeValidation(), new IntegerTypeValidation()));
  82. private RuleActivator ruleActivator = new RuleActivator(system2, db.getDbClient(), typeValidations, userSession);
  83. private QProfileRules underTest = new QProfileRulesImpl(db.getDbClient(), ruleActivator, ruleIndex, activeRuleIndexer);
  84. @Test
  85. public void system_activates_rule_without_parameters() {
  86. RuleDefinitionDto rule = createRule();
  87. QProfileDto profile = createProfile(rule);
  88. RuleActivation activation = RuleActivation.create(rule.getId(), BLOCKER, null);
  89. List<ActiveRuleChange> changes = activate(profile, activation);
  90. assertThatRuleIsActivated(profile, rule, changes, BLOCKER, null, emptyMap());
  91. assertThatProfileIsUpdatedBySystem(profile);
  92. }
  93. @Test
  94. public void user_activates_rule_without_parameters() {
  95. userSession.logIn();
  96. RuleDefinitionDto rule = createRule();
  97. QProfileDto profile = createProfile(rule);
  98. RuleActivation activation = RuleActivation.create(rule.getId(), BLOCKER, null);
  99. List<ActiveRuleChange> changes = activate(profile, activation);
  100. assertThatRuleIsActivated(profile, rule, changes, BLOCKER, null, emptyMap());
  101. assertThatProfileIsUpdatedByUser(profile);
  102. }
  103. @Test
  104. public void activate_rule_with_default_severity_and_parameters() {
  105. RuleDefinitionDto rule = createRule();
  106. RuleParamDto ruleParam = db.rules().insertRuleParam(rule, p -> p.setName("min").setDefaultValue("10"));
  107. QProfileDto profile = createProfile(rule);
  108. RuleActivation activation = RuleActivation.create(rule.getId());
  109. List<ActiveRuleChange> changes = activate(profile, activation);
  110. assertThatRuleIsActivated(profile, rule, changes, rule.getSeverityString(), null, of("min", "10"));
  111. assertThatProfileIsUpdatedBySystem(profile);
  112. }
  113. @Test
  114. public void activate_rule_with_parameters() {
  115. RuleDefinitionDto rule = createRule();
  116. RuleParamDto ruleParam = db.rules().insertRuleParam(rule, p -> p.setName("min").setDefaultValue("10"));
  117. QProfileDto profile = createProfile(rule);
  118. RuleActivation activation = RuleActivation.create(rule.getId(), null, of(ruleParam.getName(), "15"));
  119. List<ActiveRuleChange> changes = activate(profile, activation);
  120. assertThatRuleIsActivated(profile, rule, changes, rule.getSeverityString(), null, of("min", "15"));
  121. assertThatProfileIsUpdatedBySystem(profile);
  122. }
  123. @Test
  124. public void activate_rule_with_default_severity() {
  125. RuleDefinitionDto rule = createRule();
  126. QProfileDto profile = createProfile(rule);
  127. RuleActivation activation = RuleActivation.create(rule.getId());
  128. List<ActiveRuleChange> changes = activate(profile, activation);
  129. assertThatRuleIsActivated(profile, rule, changes, rule.getSeverityString(), null, emptyMap());
  130. assertThatProfileIsUpdatedBySystem(profile);
  131. }
  132. /**
  133. * SONAR-5841
  134. */
  135. @Test
  136. public void activate_rule_with_empty_parameter_having_no_default_value() {
  137. RuleDefinitionDto rule = createRule();
  138. RuleParamDto ruleParam = db.rules().insertRuleParam(rule, p -> p.setName("min").setDefaultValue("10"));
  139. QProfileDto profile = createProfile(rule);
  140. RuleActivation activation = RuleActivation.create(rule.getId(), null, of("min", ""));
  141. List<ActiveRuleChange> changes = activate(profile, activation);
  142. assertThatRuleIsActivated(profile, rule, changes, rule.getSeverityString(), null, of("min", "10"));
  143. assertThatProfileIsUpdatedBySystem(profile);
  144. }
  145. /**
  146. * // * SONAR-5840
  147. * //
  148. */
  149. @Test
  150. public void activate_rule_with_negative_integer_value_on_parameter_having_no_default_value() {
  151. RuleDefinitionDto rule = createRule();
  152. RuleParamDto paramWithoutDefault = db.rules().insertRuleParam(rule, p -> p.setName("min").setDefaultValue(null));
  153. RuleParamDto paramWithDefault = db.rules().insertRuleParam(rule, p -> p.setName("max").setDefaultValue("10"));
  154. QProfileDto profile = createProfile(rule);
  155. RuleActivation activation = RuleActivation.create(rule.getId(), null, of(paramWithoutDefault.getName(), "-10"));
  156. List<ActiveRuleChange> changes = activate(profile, activation);
  157. assertThatRuleIsActivated(profile, rule, changes, rule.getSeverityString(), null,
  158. of(paramWithoutDefault.getName(), "-10", paramWithDefault.getName(), paramWithDefault.getDefaultValue()));
  159. assertThatProfileIsUpdatedBySystem(profile);
  160. }
  161. @Test
  162. public void activation_ignores_unsupported_parameters() {
  163. RuleDefinitionDto rule = createRule();
  164. RuleParamDto param = db.rules().insertRuleParam(rule, p -> p.setName("max").setDefaultValue("10"));
  165. QProfileDto profile = createProfile(rule);
  166. RuleActivation activation = RuleActivation.create(rule.getId(), null, of("xxx", "yyy"));
  167. List<ActiveRuleChange> changes = activate(profile, activation);
  168. assertThatRuleIsActivated(profile, rule, changes, rule.getSeverityString(), null, of(param.getName(), param.getDefaultValue()));
  169. assertThatProfileIsUpdatedBySystem(profile);
  170. }
  171. @Test
  172. public void update_an_already_activated_rule() {
  173. RuleDefinitionDto rule = createRule();
  174. RuleParamDto param = db.rules().insertRuleParam(rule, p -> p.setName("max").setDefaultValue("10"));
  175. QProfileDto profile = createProfile(rule);
  176. // initial activation
  177. RuleActivation activation = RuleActivation.create(rule.getId(), MAJOR, null);
  178. activate(profile, activation);
  179. // update
  180. RuleActivation updateActivation = RuleActivation.create(rule.getId(), CRITICAL, of(param.getName(), "20"));
  181. List<ActiveRuleChange> changes = activate(profile, updateActivation);
  182. assertThatRuleIsUpdated(profile, rule, CRITICAL, null, of(param.getName(), "20"));
  183. assertThatProfileIsUpdatedBySystem(profile);
  184. }
  185. @Test
  186. public void update_activation_with_parameter_without_default_value() {
  187. RuleDefinitionDto rule = createRule();
  188. RuleParamDto paramWithoutDefault = db.rules().insertRuleParam(rule, p -> p.setName("min").setDefaultValue(null));
  189. RuleParamDto paramWithDefault = db.rules().insertRuleParam(rule, p -> p.setName("max").setDefaultValue("10"));
  190. QProfileDto profile = createProfile(rule);
  191. // initial activation -> param "max" has a default value
  192. RuleActivation activation = RuleActivation.create(rule.getId());
  193. activate(profile, activation);
  194. // update param "min", which has no default value
  195. RuleActivation updateActivation = RuleActivation.create(rule.getId(), MAJOR, of(paramWithoutDefault.getName(), "3"));
  196. List<ActiveRuleChange> changes = activate(profile, updateActivation);
  197. assertThatRuleIsUpdated(profile, rule, MAJOR, null, of(paramWithDefault.getName(), "10", paramWithoutDefault.getName(), "3"));
  198. assertThatProfileIsUpdatedBySystem(profile);
  199. }
  200. @Test
  201. public void reset_parameter_to_default_value() {
  202. RuleDefinitionDto rule = createRule();
  203. RuleParamDto paramWithDefault = db.rules().insertRuleParam(rule, p -> p.setName("max").setDefaultValue("10"));
  204. QProfileDto profile = createProfile(rule);
  205. // initial activation -> param "max" has a default value
  206. RuleActivation activation = RuleActivation.create(rule.getId(), null, of(paramWithDefault.getName(), "20"));
  207. activate(profile, activation);
  208. // reset to default_value
  209. RuleActivation updateActivation = RuleActivation.create(rule.getId(), null, of(paramWithDefault.getName(), ""));
  210. List<ActiveRuleChange> changes = activate(profile, updateActivation);
  211. assertThatRuleIsUpdated(profile, rule, rule.getSeverityString(), null, of(paramWithDefault.getName(), "10"));
  212. assertThat(changes).hasSize(1);
  213. }
  214. @Test
  215. public void update_activation_removes_parameter_without_default_value() {
  216. RuleDefinitionDto rule = createRule();
  217. RuleParamDto paramWithoutDefault = db.rules().insertRuleParam(rule, p -> p.setName("min").setDefaultValue(null));
  218. RuleParamDto paramWithDefault = db.rules().insertRuleParam(rule, p -> p.setName("max").setDefaultValue("10"));
  219. QProfileDto profile = createProfile(rule);
  220. // initial activation -> param "max" has a default value
  221. RuleActivation activation = RuleActivation.create(rule.getId(), null, of(paramWithoutDefault.getName(), "20"));
  222. activate(profile, activation);
  223. // remove parameter
  224. RuleActivation updateActivation = RuleActivation.create(rule.getId(), null, of(paramWithoutDefault.getName(), ""));
  225. List<ActiveRuleChange> changes = activate(profile, updateActivation);
  226. assertThatRuleIsUpdated(profile, rule, rule.getSeverityString(), null, of(paramWithDefault.getName(), paramWithDefault.getDefaultValue()));
  227. assertThat(changes).hasSize(1);
  228. }
  229. @Test
  230. public void update_activation_with_new_parameter() {
  231. RuleDefinitionDto rule = createRule();
  232. RuleParamDto param = db.rules().insertRuleParam(rule, p -> p.setName("max").setDefaultValue("10"));
  233. QProfileDto profile = createProfile(rule);
  234. // initial activation -> param "max" has a default value
  235. RuleActivation activation = RuleActivation.create(rule.getId());
  236. List<ActiveRuleChange> changes = activate(profile, activation);
  237. db.getDbClient().activeRuleDao().deleteParametersByRuleProfileUuids(db.getSession(), asList(profile.getRulesProfileUuid()));
  238. assertThatRuleIsActivated(profile, rule, changes, rule.getSeverityString(), null, emptyMap());
  239. // contrary to activerule, the param is supposed to be inserted but not updated
  240. RuleActivation updateActivation = RuleActivation.create(rule.getId(), null, of(param.getName(), ""));
  241. changes = activate(profile, updateActivation);
  242. assertThatRuleIsUpdated(profile, rule, rule.getSeverityString(), null, of(param.getName(), param.getDefaultValue()));
  243. assertThat(changes).hasSize(1);
  244. }
  245. @Test
  246. public void ignore_activation_without_changes() {
  247. RuleDefinitionDto rule = createRule();
  248. QProfileDto profile = createProfile(rule);
  249. // initial activation
  250. RuleActivation activation = RuleActivation.create(rule.getId());
  251. activate(profile, activation);
  252. // update with exactly the same severity and params
  253. activation = RuleActivation.create(rule.getId());
  254. List<ActiveRuleChange> changes = activate(profile, activation);
  255. assertThat(changes).isEmpty();
  256. }
  257. @Test
  258. public void do_not_change_severity_and_params_if_unset_and_already_activated() {
  259. RuleDefinitionDto rule = createRule();
  260. RuleParamDto param = db.rules().insertRuleParam(rule, p -> p.setName("max").setDefaultValue("10"));
  261. QProfileDto profile = createProfile(rule);
  262. // initial activation -> param "max" has a default value
  263. RuleActivation activation = RuleActivation.create(rule.getId(), BLOCKER, of(param.getName(), "20"));
  264. activate(profile, activation);
  265. // update without any severity or params => keep
  266. RuleActivation update = RuleActivation.create(rule.getId());
  267. List<ActiveRuleChange> changes = activate(profile, update);
  268. assertThat(changes).isEmpty();
  269. }
  270. @Test
  271. public void fail_to_activate_rule_if_profile_is_on_different_languages() {
  272. RuleDefinitionDto rule = createJavaRule();
  273. QProfileDto profile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage("js"));
  274. RuleActivation activation = RuleActivation.create(rule.getId());
  275. expectFailure("java rule " + rule.getKey() + " cannot be activated on js profile " + profile.getKee(), () -> activate(profile, activation));
  276. }
  277. @Test
  278. public void fail_to_activate_rule_if_rule_has_REMOVED_status() {
  279. RuleDefinitionDto rule = db.rules().insert(r -> r.setStatus(RuleStatus.REMOVED));
  280. QProfileDto profile = createProfile(rule);
  281. RuleActivation activation = RuleActivation.create(rule.getId());
  282. expectFailure("Rule was removed: " + rule.getKey(), () -> activate(profile, activation));
  283. }
  284. @Test
  285. public void fail_to_activate_if_template() {
  286. RuleDefinitionDto rule = db.rules().insert(r -> r.setIsTemplate(true));
  287. QProfileDto profile = createProfile(rule);
  288. RuleActivation activation = RuleActivation.create(rule.getId());
  289. expectFailure("Rule template can't be activated on a Quality profile: " + rule.getKey(), () -> activate(profile, activation));
  290. }
  291. @Test
  292. public void fail_to_activate_if_invalid_parameter() {
  293. RuleDefinitionDto rule = createRule();
  294. RuleParamDto param = db.rules().insertRuleParam(rule, p -> p.setName("max").setDefaultValue("10").setType(PropertyType.INTEGER.name()));
  295. QProfileDto profile = createProfile(rule);
  296. RuleActivation activation = RuleActivation.create(rule.getId(), null, of(param.getName(), "foo"));
  297. expectFailure("Value 'foo' must be an integer.", () -> activate(profile, activation));
  298. }
  299. @Test
  300. public void ignore_parameters_when_activating_custom_rule() {
  301. RuleDefinitionDto templateRule = db.rules().insert(r -> r.setIsTemplate(true));
  302. RuleParamDto templateParam = db.rules().insertRuleParam(templateRule, p -> p.setName("format"));
  303. RuleDefinitionDto customRule = db.rules().insert(newCustomRule(templateRule));
  304. RuleParamDto customParam = db.rules().insertRuleParam(customRule, p -> p.setName("format").setDefaultValue("txt"));
  305. QProfileDto profile = createProfile(customRule);
  306. // initial activation
  307. RuleActivation activation = RuleActivation.create(customRule.getId(), MAJOR, emptyMap());
  308. activate(profile, activation);
  309. assertThatRuleIsActivated(profile, customRule, null, MAJOR, null, of("format", "txt"));
  310. // update -> parameter is not changed
  311. RuleActivation updateActivation = RuleActivation.create(customRule.getId(), BLOCKER, of("format", "xml"));
  312. activate(profile, updateActivation);
  313. assertThatRuleIsActivated(profile, customRule, null, BLOCKER, null, of("format", "txt"));
  314. }
  315. @Test
  316. public void user_deactivates_a_rule() {
  317. userSession.logIn();
  318. RuleDefinitionDto rule = createRule();
  319. QProfileDto profile = createProfile(rule);
  320. RuleActivation activation = RuleActivation.create(rule.getId());
  321. activate(profile, activation);
  322. List<ActiveRuleChange> changes = deactivate(profile, rule);
  323. verifyNoActiveRules();
  324. assertThatProfileIsUpdatedByUser(profile);
  325. assertThat(changes).hasSize(1);
  326. assertThat(changes.get(0).getType()).isEqualTo(ActiveRuleChange.Type.DEACTIVATED);
  327. }
  328. @Test
  329. public void system_deactivates_a_rule() {
  330. RuleDefinitionDto rule = createRule();
  331. QProfileDto profile = createProfile(rule);
  332. RuleActivation activation = RuleActivation.create(rule.getId());
  333. activate(profile, activation);
  334. List<ActiveRuleChange> changes = deactivate(profile, rule);
  335. verifyNoActiveRules();
  336. assertThatProfileIsUpdatedBySystem(profile);
  337. assertThatChangeIsDeactivation(changes, rule);
  338. }
  339. private void assertThatChangeIsDeactivation(List<ActiveRuleChange> changes, RuleDefinitionDto rule) {
  340. assertThat(changes).hasSize(1);
  341. ActiveRuleChange change = changes.get(0);
  342. assertThat(change.getType()).isEqualTo(ActiveRuleChange.Type.DEACTIVATED);
  343. assertThat(change.getKey().getRuleKey()).isEqualTo(rule.getKey());
  344. }
  345. @Test
  346. public void ignore_deactivation_if_rule_is_not_activated() {
  347. RuleDefinitionDto rule = createRule();
  348. QProfileDto profile = createProfile(rule);
  349. List<ActiveRuleChange> changes = deactivate(profile, rule);
  350. verifyNoActiveRules();
  351. assertThat(changes).hasSize(0);
  352. }
  353. @Test
  354. public void deactivate_rule_that_has_REMOVED_status() {
  355. RuleDefinitionDto rule = createRule();
  356. QProfileDto profile = createProfile(rule);
  357. RuleActivation activation = RuleActivation.create(rule.getId());
  358. activate(profile, activation);
  359. rule.setStatus(RuleStatus.REMOVED);
  360. db.getDbClient().ruleDao().update(db.getSession(), rule);
  361. List<ActiveRuleChange> changes = deactivate(profile, rule);
  362. verifyNoActiveRules();
  363. assertThatChangeIsDeactivation(changes, rule);
  364. }
  365. @Test
  366. public void activation_on_child_profile_is_propagated_to_descendants() {
  367. RuleDefinitionDto rule = createRule();
  368. QProfileDto parentProfile = createProfile(rule);
  369. QProfileDto childProfile = createChildProfile(parentProfile);
  370. QProfileDto grandChildProfile = createChildProfile(childProfile);
  371. List<ActiveRuleChange> changes = activate(childProfile, RuleActivation.create(rule.getId()));
  372. assertThatProfileHasNoActiveRules(parentProfile);
  373. assertThatRuleIsActivated(childProfile, rule, changes, rule.getSeverityString(), null, emptyMap());
  374. assertThatRuleIsActivated(grandChildProfile, rule, changes, rule.getSeverityString(), INHERITED, emptyMap());
  375. }
  376. @Test
  377. public void update_on_child_profile_is_propagated_to_descendants() {
  378. RuleDefinitionDto rule = createRule();
  379. RuleParamDto param = db.rules().insertRuleParam(rule);
  380. QProfileDto parentProfile = createProfile(rule);
  381. QProfileDto childProfile = createChildProfile(parentProfile);
  382. QProfileDto grandChildProfile = createChildProfile(childProfile);
  383. RuleActivation initialActivation = RuleActivation.create(rule.getId(), MAJOR, of(param.getName(), "foo"));
  384. activate(childProfile, initialActivation);
  385. RuleActivation updateActivation = RuleActivation.create(rule.getId(), CRITICAL, of(param.getName(), "bar"));
  386. List<ActiveRuleChange> changes = activate(childProfile, updateActivation);
  387. assertThatProfileHasNoActiveRules(parentProfile);
  388. assertThatRuleIsUpdated(childProfile, rule, CRITICAL, null, of(param.getName(), "bar"));
  389. assertThatRuleIsUpdated(grandChildProfile, rule, CRITICAL, INHERITED, of(param.getName(), "bar"));
  390. assertThat(changes).hasSize(2);
  391. }
  392. @Test
  393. public void override_activation_of_inherited_profile() {
  394. RuleDefinitionDto rule = createRule();
  395. RuleParamDto param = db.rules().insertRuleParam(rule);
  396. QProfileDto parentProfile = createProfile(rule);
  397. QProfileDto childProfile = createChildProfile(parentProfile);
  398. QProfileDto grandChildProfile = createChildProfile(childProfile);
  399. RuleActivation initialActivation = RuleActivation.create(rule.getId(), MAJOR, of(param.getName(), "foo"));
  400. activate(childProfile, initialActivation);
  401. RuleActivation overrideActivation = RuleActivation.create(rule.getId(), CRITICAL, of(param.getName(), "bar"));
  402. List<ActiveRuleChange> changes = activate(grandChildProfile, overrideActivation);
  403. assertThatProfileHasNoActiveRules(parentProfile);
  404. assertThatRuleIsUpdated(childProfile, rule, MAJOR, null, of(param.getName(), "foo"));
  405. assertThatRuleIsUpdated(grandChildProfile, rule, CRITICAL, ActiveRuleInheritance.OVERRIDES, of(param.getName(), "bar"));
  406. assertThat(changes).hasSize(1);
  407. }
  408. @Test
  409. public void updated_activation_on_parent_is_not_propagated_to_overridden_profiles() {
  410. RuleDefinitionDto rule = createRule();
  411. RuleParamDto param = db.rules().insertRuleParam(rule);
  412. QProfileDto parentProfile = createProfile(rule);
  413. QProfileDto childProfile = createChildProfile(parentProfile);
  414. QProfileDto grandChildProfile = createChildProfile(childProfile);
  415. RuleActivation initialActivation = RuleActivation.create(rule.getId(), MAJOR, of(param.getName(), "foo"));
  416. activate(childProfile, initialActivation);
  417. RuleActivation overrideActivation = RuleActivation.create(rule.getId(), CRITICAL, of(param.getName(), "bar"));
  418. activate(grandChildProfile, overrideActivation);
  419. // update child --> do not touch grandChild
  420. RuleActivation updateActivation = RuleActivation.create(rule.getId(), BLOCKER, of(param.getName(), "baz"));
  421. List<ActiveRuleChange> changes = activate(childProfile, updateActivation);
  422. assertThatProfileHasNoActiveRules(parentProfile);
  423. assertThatRuleIsUpdated(childProfile, rule, BLOCKER, null, of(param.getName(), "baz"));
  424. assertThatRuleIsUpdated(grandChildProfile, rule, CRITICAL, ActiveRuleInheritance.OVERRIDES, of(param.getName(), "bar"));
  425. assertThat(changes).hasSize(1);
  426. }
  427. @Test
  428. public void reset_on_parent_is_not_propagated_to_overridden_profiles() {
  429. RuleDefinitionDto rule = createRule();
  430. RuleParamDto param = db.rules().insertRuleParam(rule);
  431. QProfileDto parentProfile = createProfile(rule);
  432. QProfileDto childProfile = createChildProfile(parentProfile);
  433. QProfileDto grandChildProfile = createChildProfile(childProfile);
  434. RuleActivation initialActivation = RuleActivation.create(rule.getId(), MAJOR, of(param.getName(), "foo"));
  435. activate(parentProfile, initialActivation);
  436. RuleActivation overrideActivation = RuleActivation.create(rule.getId(), CRITICAL, of(param.getName(), "bar"));
  437. activate(grandChildProfile, overrideActivation);
  438. // reset parent --> touch child but not grandChild
  439. RuleActivation updateActivation = RuleActivation.createReset(rule.getId());
  440. List<ActiveRuleChange> changes = activate(parentProfile, updateActivation);
  441. assertThatRuleIsUpdated(parentProfile, rule, rule.getSeverityString(), null, of(param.getName(), param.getDefaultValue()));
  442. assertThatRuleIsUpdated(childProfile, rule, rule.getSeverityString(), INHERITED, of(param.getName(), param.getDefaultValue()));
  443. assertThatRuleIsUpdated(grandChildProfile, rule, CRITICAL, ActiveRuleInheritance.OVERRIDES, of(param.getName(), "bar"));
  444. assertThat(changes).hasSize(2);
  445. }
  446. @Test
  447. public void active_on_parent_a_rule_already_activated_on_child() {
  448. RuleDefinitionDto rule = createRule();
  449. RuleParamDto param = db.rules().insertRuleParam(rule);
  450. QProfileDto parentProfile = createProfile(rule);
  451. QProfileDto childProfile = createChildProfile(parentProfile);
  452. RuleActivation childActivation = RuleActivation.create(rule.getId(), MAJOR, of(param.getName(), "foo"));
  453. activate(childProfile, childActivation);
  454. RuleActivation parentActivation = RuleActivation.create(rule.getId(), CRITICAL, of(param.getName(), "bar"));
  455. List<ActiveRuleChange> changes = activate(parentProfile, parentActivation);
  456. assertThatRuleIsUpdated(parentProfile, rule, CRITICAL, null, of(param.getName(), "bar"));
  457. assertThatRuleIsUpdated(childProfile, rule, MAJOR, ActiveRuleInheritance.OVERRIDES, of(param.getName(), "foo"));
  458. assertThat(changes).hasSize(2);
  459. }
  460. @Test
  461. public void do_not_mark_as_overridden_if_same_values_than_parent() {
  462. RuleDefinitionDto rule = createRule();
  463. RuleParamDto param = db.rules().insertRuleParam(rule);
  464. QProfileDto parentProfile = createProfile(rule);
  465. QProfileDto childProfile = createChildProfile(parentProfile);
  466. RuleActivation parentActivation = RuleActivation.create(rule.getId(), MAJOR, of(param.getName(), "foo"));
  467. activate(parentProfile, parentActivation);
  468. RuleActivation overrideActivation = RuleActivation.create(rule.getId(), MAJOR, of(param.getName(), "foo"));
  469. List<ActiveRuleChange> changes = activate(childProfile, overrideActivation);
  470. assertThatRuleIsUpdated(childProfile, rule, MAJOR, INHERITED, of(param.getName(), "foo"));
  471. assertThat(changes).hasSize(0);
  472. }
  473. @Test
  474. public void propagate_deactivation_on_children() {
  475. RuleDefinitionDto rule = createRule();
  476. QProfileDto parentProfile = createProfile(rule);
  477. QProfileDto childProfile = createChildProfile(parentProfile);
  478. RuleActivation activation = RuleActivation.create(rule.getId());
  479. List<ActiveRuleChange> changes = activate(parentProfile, activation);
  480. assertThatRuleIsActivated(parentProfile, rule, changes, rule.getSeverityString(), null, emptyMap());
  481. assertThatRuleIsActivated(childProfile, rule, changes, rule.getSeverityString(), INHERITED, emptyMap());
  482. changes = deactivate(parentProfile, rule);
  483. assertThatProfileHasNoActiveRules(parentProfile);
  484. assertThatProfileHasNoActiveRules(childProfile);
  485. assertThat(changes).hasSize(2);
  486. }
  487. @Test
  488. public void propagate_deactivation_on_children_even_when_overridden() {
  489. RuleDefinitionDto rule = createRule();
  490. QProfileDto parentProfile = createProfile(rule);
  491. QProfileDto childProfile = createChildProfile(parentProfile);
  492. RuleActivation activation = RuleActivation.create(rule.getId());
  493. List<ActiveRuleChange> changes = activate(parentProfile, activation);
  494. assertThatRuleIsActivated(parentProfile, rule, changes, rule.getSeverityString(), null, emptyMap());
  495. assertThatRuleIsActivated(childProfile, rule, changes, rule.getSeverityString(), INHERITED, emptyMap());
  496. activation = RuleActivation.create(rule.getId(), CRITICAL, null);
  497. activate(childProfile, activation);
  498. changes = deactivate(parentProfile, rule);
  499. assertThatProfileHasNoActiveRules(parentProfile);
  500. assertThatProfileHasNoActiveRules(childProfile);
  501. assertThat(changes).hasSize(2);
  502. }
  503. @Test
  504. public void cannot_deactivate_rule_inherited() {
  505. RuleDefinitionDto rule = createRule();
  506. QProfileDto parentProfile = createProfile(rule);
  507. QProfileDto childProfile = createChildProfile(parentProfile);
  508. RuleActivation activation = RuleActivation.create(rule.getId());
  509. List<ActiveRuleChange> changes = activate(parentProfile, activation);
  510. assertThatRuleIsActivated(parentProfile, rule, changes, rule.getSeverityString(), null, emptyMap());
  511. assertThatRuleIsActivated(childProfile, rule, changes, rule.getSeverityString(), INHERITED, emptyMap());
  512. expectedException.expect(BadRequestException.class);
  513. expectedException.expectMessage("Cannot deactivate inherited rule");
  514. deactivate(childProfile, rule);
  515. }
  516. @Test
  517. public void reset_child_profile_do_not_change_parent() {
  518. RuleDefinitionDto rule = createRule();
  519. QProfileDto parentProfile = createProfile(rule);
  520. QProfileDto childProfile = createChildProfile(parentProfile);
  521. RuleActivation activation = RuleActivation.create(rule.getId(), CRITICAL, null);
  522. List<ActiveRuleChange> changes = activate(parentProfile, activation);
  523. assertThatRuleIsActivated(parentProfile, rule, changes, CRITICAL, null, emptyMap());
  524. assertThatRuleIsActivated(childProfile, rule, changes, CRITICAL, INHERITED, emptyMap());
  525. assertThat(changes).hasSize(2);
  526. RuleActivation childActivation = RuleActivation.create(rule.getId(), BLOCKER, null);
  527. changes = activate(childProfile, childActivation);
  528. assertThatRuleIsUpdated(childProfile, rule, BLOCKER, ActiveRuleInheritance.OVERRIDES, emptyMap());
  529. assertThat(changes).hasSize(1);
  530. RuleActivation resetActivation = RuleActivation.createReset(rule.getId());
  531. changes = activate(childProfile, resetActivation);
  532. assertThatRuleIsUpdated(childProfile, rule, CRITICAL, INHERITED, emptyMap());
  533. assertThatRuleIsUpdated(parentProfile, rule, CRITICAL, null, emptyMap());
  534. assertThat(changes).hasSize(1);
  535. }
  536. @Test
  537. public void reset_parent_is_not_propagated_when_child_overrides() {
  538. RuleDefinitionDto rule = createRule();
  539. QProfileDto baseProfile = createProfile(rule);
  540. QProfileDto childProfile = createChildProfile(baseProfile);
  541. QProfileDto grandChildProfile = createChildProfile(childProfile);
  542. RuleActivation activation = RuleActivation.create(rule.getId(), CRITICAL, null);
  543. List<ActiveRuleChange> changes = activate(baseProfile, activation);
  544. assertThatRuleIsActivated(baseProfile, rule, changes, CRITICAL, null, emptyMap());
  545. assertThatRuleIsActivated(childProfile, rule, changes, CRITICAL, INHERITED, emptyMap());
  546. assertThatRuleIsActivated(grandChildProfile, rule, changes, CRITICAL, INHERITED, emptyMap());
  547. assertThat(changes).hasSize(3);
  548. RuleActivation childActivation = RuleActivation.create(rule.getId(), BLOCKER, null);
  549. changes = activate(childProfile, childActivation);
  550. assertThatRuleIsUpdated(childProfile, rule, BLOCKER, ActiveRuleInheritance.OVERRIDES, emptyMap());
  551. assertThatRuleIsUpdated(grandChildProfile, rule, BLOCKER, INHERITED, emptyMap());
  552. assertThat(changes).hasSize(2);
  553. // Reset on parent do not change child nor grandchild
  554. RuleActivation resetActivation = RuleActivation.createReset(rule.getId());
  555. changes = activate(baseProfile, resetActivation);
  556. assertThatRuleIsUpdated(baseProfile, rule, rule.getSeverityString(), null, emptyMap());
  557. assertThatRuleIsUpdated(childProfile, rule, BLOCKER, ActiveRuleInheritance.OVERRIDES, emptyMap());
  558. assertThatRuleIsUpdated(grandChildProfile, rule, BLOCKER, INHERITED, emptyMap());
  559. assertThat(changes).hasSize(1);
  560. // Reset on child change grandchild
  561. resetActivation = RuleActivation.createReset(rule.getId());
  562. changes = activate(childProfile, resetActivation);
  563. assertThatRuleIsUpdated(baseProfile, rule, rule.getSeverityString(), null, emptyMap());
  564. assertThatRuleIsUpdated(childProfile, rule, rule.getSeverityString(), INHERITED, emptyMap());
  565. assertThatRuleIsUpdated(grandChildProfile, rule, rule.getSeverityString(), INHERITED, emptyMap());
  566. assertThat(changes).hasSize(2);
  567. }
  568. @Test
  569. public void ignore_reset_if_not_activated() {
  570. RuleDefinitionDto rule = createRule();
  571. QProfileDto parentProfile = createProfile(rule);
  572. createChildProfile(parentProfile);
  573. RuleActivation resetActivation = RuleActivation.createReset(rule.getId());
  574. List<ActiveRuleChange> changes = activate(parentProfile, resetActivation);
  575. verifyNoActiveRules();
  576. assertThat(changes).hasSize(0);
  577. }
  578. @Test
  579. public void bulk_activation() {
  580. int bulkSize = SearchOptions.MAX_LIMIT + 10 + new Random().nextInt(100);
  581. String language = randomAlphanumeric(10);
  582. String repositoryKey = randomAlphanumeric(10);
  583. QProfileDto profile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(language));
  584. List<RuleDto> rules = new ArrayList<>();
  585. IntStream.rangeClosed(1, bulkSize).forEach(
  586. i -> rules.add(db.rules().insertRule(r -> r.setLanguage(language).setRepositoryKey(repositoryKey))));
  587. verifyNoActiveRules();
  588. ruleIndexer.indexOnStartup(ruleIndexer.getIndexTypes());
  589. RuleQuery ruleQuery = new RuleQuery()
  590. .setRepositories(singletonList(repositoryKey));
  591. BulkChangeResult bulkChangeResult = underTest.bulkActivateAndCommit(db.getSession(), profile, ruleQuery, MINOR);
  592. assertThat(bulkChangeResult.countFailed()).isEqualTo(0);
  593. assertThat(bulkChangeResult.countSucceeded()).isEqualTo(bulkSize);
  594. assertThat(bulkChangeResult.getChanges()).hasSize(bulkSize);
  595. assertThat(db.getDbClient().activeRuleDao().selectByProfile(db.getSession(), profile)).hasSize(bulkSize);
  596. rules.stream().forEach(
  597. r -> assertThatRuleIsActivated(profile, r.getDefinition(), null, MINOR, null, emptyMap()));
  598. }
  599. @Test
  600. public void bulk_deactivation() {
  601. int bulkSize = SearchOptions.MAX_LIMIT + 10 + new Random().nextInt(100);
  602. String language = randomAlphanumeric(10);
  603. String repositoryKey = randomAlphanumeric(10);
  604. QProfileDto profile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(language));
  605. List<RuleDto> rules = new ArrayList<>();
  606. IntStream.rangeClosed(1, bulkSize).forEach(
  607. i -> rules.add(db.rules().insertRule(r -> r.setLanguage(language).setRepositoryKey(repositoryKey))));
  608. verifyNoActiveRules();
  609. ruleIndexer.indexOnStartup(ruleIndexer.getIndexTypes());
  610. RuleQuery ruleQuery = new RuleQuery()
  611. .setRepositories(singletonList(repositoryKey));
  612. BulkChangeResult bulkChangeResult = underTest.bulkActivateAndCommit(db.getSession(), profile, ruleQuery, MINOR);
  613. assertThat(bulkChangeResult.countFailed()).isEqualTo(0);
  614. assertThat(bulkChangeResult.countSucceeded()).isEqualTo(bulkSize);
  615. assertThat(bulkChangeResult.getChanges()).hasSize(bulkSize);
  616. assertThat(db.getDbClient().activeRuleDao().selectByProfile(db.getSession(), profile)).hasSize(bulkSize);
  617. // Now deactivate all rules
  618. bulkChangeResult = underTest.bulkDeactivateAndCommit(db.getSession(), profile, ruleQuery);
  619. assertThat(bulkChangeResult.countFailed()).isEqualTo(0);
  620. assertThat(bulkChangeResult.countSucceeded()).isEqualTo(bulkSize);
  621. assertThat(bulkChangeResult.getChanges()).hasSize(bulkSize);
  622. assertThat(db.getDbClient().activeRuleDao().selectByProfile(db.getSession(), profile)).hasSize(0);
  623. rules.stream().forEach(
  624. r -> assertThatRuleIsNotPresent(profile, r.getDefinition()));
  625. }
  626. @Test
  627. public void bulk_deactivation_ignores_errors() {
  628. RuleDefinitionDto rule = createRule();
  629. QProfileDto parentProfile = createProfile(rule);
  630. QProfileDto childProfile = createChildProfile(parentProfile);
  631. List<ActiveRuleChange> changes = activate(parentProfile, RuleActivation.create(rule.getId()));
  632. assertThatRuleIsActivated(parentProfile, rule, null, rule.getSeverityString(), null, emptyMap());
  633. assertThatRuleIsActivated(childProfile, rule, null, rule.getSeverityString(), INHERITED, emptyMap());
  634. ruleIndexer.indexOnStartup(ruleIndexer.getIndexTypes());
  635. RuleQuery ruleQuery = new RuleQuery()
  636. .setQProfile(childProfile);
  637. BulkChangeResult bulkChangeResult = underTest.bulkDeactivateAndCommit(db.getSession(), childProfile, ruleQuery);
  638. assertThat(bulkChangeResult.countFailed()).isEqualTo(1);
  639. assertThat(bulkChangeResult.countSucceeded()).isEqualTo(0);
  640. assertThat(bulkChangeResult.getChanges()).hasSize(0);
  641. assertThatRuleIsActivated(parentProfile, rule, null, rule.getSeverityString(), null, emptyMap());
  642. assertThatRuleIsActivated(childProfile, rule, null, rule.getSeverityString(), INHERITED, emptyMap());
  643. }
  644. @Test
  645. public void bulk_change_severity() {
  646. RuleDefinitionDto rule1 = createJavaRule();
  647. RuleDefinitionDto rule2 = createJavaRule();
  648. QProfileDto parentProfile = createProfile(rule1);
  649. QProfileDto childProfile = createChildProfile(parentProfile);
  650. QProfileDto grandchildProfile = createChildProfile(childProfile);
  651. activate(parentProfile, RuleActivation.create(rule1.getId()));
  652. activate(parentProfile, RuleActivation.create(rule2.getId()));
  653. ruleIndexer.indexOnStartup(ruleIndexer.getIndexTypes());
  654. RuleQuery query = new RuleQuery()
  655. .setRuleKey(rule1.getRuleKey())
  656. .setQProfile(parentProfile);
  657. BulkChangeResult result = underTest.bulkActivateAndCommit(db.getSession(), parentProfile, query, "BLOCKER");
  658. assertThat(result.getChanges()).hasSize(3);
  659. assertThat(result.countSucceeded()).isEqualTo(1);
  660. assertThat(result.countFailed()).isEqualTo(0);
  661. // Rule1 must be activated with BLOCKER on all profiles
  662. assertThatRuleIsActivated(parentProfile, rule1, null, BLOCKER, null, emptyMap());
  663. assertThatRuleIsActivated(childProfile, rule1, null, BLOCKER, INHERITED, emptyMap());
  664. assertThatRuleIsActivated(grandchildProfile, rule1, null, BLOCKER, INHERITED, emptyMap());
  665. // Rule2 did not changed
  666. assertThatRuleIsActivated(parentProfile, rule2, null, rule2.getSeverityString(), null, emptyMap());
  667. assertThatRuleIsActivated(childProfile, rule2, null, rule2.getSeverityString(), INHERITED, emptyMap());
  668. assertThatRuleIsActivated(grandchildProfile, rule2, null, rule2.getSeverityString(), INHERITED, emptyMap());
  669. }
  670. @Test
  671. public void delete_rule_from_all_profiles() {
  672. RuleDefinitionDto rule = createRule();
  673. QProfileDto parentProfile = createProfile(rule);
  674. QProfileDto childProfile = createChildProfile(parentProfile);
  675. QProfileDto grandChildProfile = createChildProfile(childProfile);
  676. RuleActivation activation = RuleActivation.create(rule.getId(), CRITICAL, null);
  677. activate(parentProfile, activation);
  678. RuleActivation overrideActivation = RuleActivation.create(rule.getId(), BLOCKER, null);
  679. activate(grandChildProfile, overrideActivation);
  680. // Reset on parent do not change child nor grandchild
  681. List<ActiveRuleChange> changes = underTest.deleteRule(db.getSession(), rule);
  682. assertThatRuleIsNotPresent(parentProfile, rule);
  683. assertThatRuleIsNotPresent(childProfile, rule);
  684. assertThatRuleIsNotPresent(grandChildProfile, rule);
  685. assertThat(changes)
  686. .extracting(ActiveRuleChange::getType)
  687. .containsOnly(ActiveRuleChange.Type.DEACTIVATED)
  688. .hasSize(3);
  689. }
  690. @Test
  691. public void activation_fails_when_profile_is_built_in() {
  692. RuleDefinitionDto rule = createRule();
  693. QProfileDto builtInProfile = db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(rule.getLanguage()).setIsBuiltIn(true));
  694. expectedException.expect(IllegalArgumentException.class);
  695. expectedException.expectMessage("The built-in profile " + builtInProfile.getName() + " is read-only and can't be updated");
  696. underTest.activateAndCommit(db.getSession(), builtInProfile, singleton(RuleActivation.create(rule.getId())));
  697. }
  698. private void assertThatProfileHasNoActiveRules(QProfileDto profile) {
  699. List<OrgActiveRuleDto> activeRules = db.getDbClient().activeRuleDao().selectByProfile(db.getSession(), profile);
  700. assertThat(activeRules).isEmpty();
  701. }
  702. private List<ActiveRuleChange> deactivate(QProfileDto profile, RuleDefinitionDto rule) {
  703. return underTest.deactivateAndCommit(db.getSession(), profile, singleton(rule.getId()));
  704. }
  705. private List<ActiveRuleChange> activate(QProfileDto profile, RuleActivation activation) {
  706. return underTest.activateAndCommit(db.getSession(), profile, singleton(activation));
  707. }
  708. private QProfileDto createProfile(RuleDefinitionDto rule) {
  709. return db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p.setLanguage(rule.getLanguage()));
  710. }
  711. private QProfileDto createChildProfile(QProfileDto parent) {
  712. return db.qualityProfiles().insert(db.getDefaultOrganization(), p -> p
  713. .setLanguage(parent.getLanguage())
  714. .setParentKee(parent.getKee())
  715. .setName("Child of " + parent.getName()));
  716. }
  717. private void assertThatProfileIsUpdatedByUser(QProfileDto profile) {
  718. QProfileDto loaded = db.getDbClient().qualityProfileDao().selectByUuid(db.getSession(), profile.getKee());
  719. assertThat(loaded.getUserUpdatedAt()).isNotNull();
  720. assertThat(loaded.getRulesUpdatedAt()).isNotEmpty();
  721. }
  722. private void assertThatProfileIsUpdatedBySystem(QProfileDto profile) {
  723. QProfileDto loaded = db.getDbClient().qualityProfileDao().selectByUuid(db.getSession(), profile.getKee());
  724. assertThat(loaded.getUserUpdatedAt()).isNull();
  725. assertThat(loaded.getRulesUpdatedAt()).isNotEmpty();
  726. }
  727. private void assertThatRuleIsActivated(QProfileDto profile, RuleDefinitionDto rule, @Nullable List<ActiveRuleChange> changes,
  728. String expectedSeverity, @Nullable ActiveRuleInheritance expectedInheritance, Map<String, String> expectedParams) {
  729. OrgActiveRuleDto activeRule = db.getDbClient().activeRuleDao().selectByProfile(db.getSession(), profile)
  730. .stream()
  731. .filter(ar -> ar.getRuleKey().equals(rule.getKey()))
  732. .findFirst()
  733. .orElseThrow(IllegalStateException::new);
  734. assertThat(activeRule.getSeverityString()).isEqualTo(expectedSeverity);
  735. assertThat(activeRule.getInheritance()).isEqualTo(expectedInheritance != null ? expectedInheritance.name() : null);
  736. assertThat(activeRule.getCreatedAt()).isNotNull();
  737. assertThat(activeRule.getUpdatedAt()).isNotNull();
  738. List<ActiveRuleParamDto> params = db.getDbClient().activeRuleDao().selectParamsByActiveRuleId(db.getSession(), activeRule.getId());
  739. assertThat(params).hasSize(expectedParams.size());
  740. if (changes != null) {
  741. ActiveRuleChange change = changes.stream()
  742. .filter(c -> c.getActiveRule().getId().equals(activeRule.getId()))
  743. .findFirst().orElseThrow(IllegalStateException::new);
  744. assertThat(change.getInheritance()).isEqualTo(expectedInheritance);
  745. assertThat(change.getSeverity()).isEqualTo(expectedSeverity);
  746. assertThat(change.getType()).isEqualTo(ActiveRuleChange.Type.ACTIVATED);
  747. }
  748. }
  749. private void assertThatRuleIsNotPresent(QProfileDto profile, RuleDefinitionDto rule) {
  750. Optional<OrgActiveRuleDto> activeRule = db.getDbClient().activeRuleDao().selectByProfile(db.getSession(), profile)
  751. .stream()
  752. .filter(ar -> ar.getRuleKey().equals(rule.getKey()))
  753. .findFirst();
  754. assertThat(activeRule).isEmpty();
  755. }
  756. private void assertThatRuleIsUpdated(QProfileDto profile, RuleDefinitionDto rule,
  757. String expectedSeverity, @Nullable ActiveRuleInheritance expectedInheritance, Map<String, String> expectedParams) {
  758. OrgActiveRuleDto activeRule = db.getDbClient().activeRuleDao().selectByProfile(db.getSession(), profile)
  759. .stream()
  760. .filter(ar -> ar.getRuleKey().equals(rule.getKey()))
  761. .findFirst()
  762. .orElseThrow(IllegalStateException::new);
  763. assertThat(activeRule.getSeverityString()).isEqualTo(expectedSeverity);
  764. assertThat(activeRule.getInheritance()).isEqualTo(expectedInheritance != null ? expectedInheritance.name() : null);
  765. assertThat(activeRule.getCreatedAt()).isNotNull();
  766. assertThat(activeRule.getUpdatedAt()).isNotNull();
  767. List<ActiveRuleParamDto> params = db.getDbClient().activeRuleDao().selectParamsByActiveRuleId(db.getSession(), activeRule.getId());
  768. assertThat(params).hasSize(expectedParams.size());
  769. }
  770. private void expectFailure(String expectedMessage, Runnable runnable) {
  771. try {
  772. runnable.run();
  773. fail();
  774. } catch (BadRequestException e) {
  775. assertThat(e.getMessage()).isEqualTo(expectedMessage);
  776. }
  777. verifyNoActiveRules();
  778. }
  779. private void verifyNoActiveRules() {
  780. assertThat(db.countRowsOfTable(db.getSession(), "active_rules")).isEqualTo(0);
  781. }
  782. private RuleDefinitionDto createRule() {
  783. return db.rules().insert(r -> r.setSeverity(Severity.MAJOR));
  784. }
  785. private RuleDefinitionDto createJavaRule() {
  786. return db.rules().insert(r -> r.setSeverity(Severity.MAJOR).setLanguage("java"));
  787. }
  788. }