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.

RuleRepositoryImplTest.java 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  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.ce.task.projectanalysis.issue;
  21. import com.google.common.collect.ImmutableList;
  22. import com.google.common.collect.ImmutableSet;
  23. import java.util.Optional;
  24. import org.junit.Before;
  25. import org.junit.Test;
  26. import org.junit.rules.ExpectedException;
  27. import org.sonar.api.rule.RuleKey;
  28. import org.sonar.api.rule.RuleStatus;
  29. import org.sonar.api.rules.RuleType;
  30. import org.sonar.api.utils.System2;
  31. import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
  32. import org.sonar.core.util.SequenceUuidFactory;
  33. import org.sonar.db.DbClient;
  34. import org.sonar.db.DbSession;
  35. import org.sonar.db.DbTester;
  36. import org.sonar.db.rule.DeprecatedRuleKeyDto;
  37. import org.sonar.db.rule.RuleDao;
  38. import org.sonar.db.rule.RuleDefinitionDto;
  39. import org.sonar.db.rule.RuleDto;
  40. import org.sonar.scanner.protocol.output.ScannerReport;
  41. import org.sonar.server.rule.index.RuleIndexer;
  42. import static org.assertj.core.api.Assertions.assertThat;
  43. import static org.mockito.ArgumentMatchers.any;
  44. import static org.mockito.ArgumentMatchers.anyBoolean;
  45. import static org.mockito.ArgumentMatchers.eq;
  46. import static org.mockito.Mockito.mock;
  47. import static org.mockito.Mockito.reset;
  48. import static org.mockito.Mockito.verify;
  49. import static org.mockito.Mockito.verifyNoMoreInteractions;
  50. import static org.mockito.Mockito.when;
  51. import static org.mockito.internal.verification.VerificationModeFactory.times;
  52. public class RuleRepositoryImplTest {
  53. private static final RuleDto AB_RULE = createABRuleDto().setUuid("rule-uuid");
  54. private static final RuleKey AB_RULE_DEPRECATED_KEY_1 = RuleKey.of("old_a", "old_b");
  55. private static final RuleKey AB_RULE_DEPRECATED_KEY_2 = RuleKey.of(AB_RULE.getRepositoryKey(), "old_b");
  56. private static final RuleKey DEPRECATED_KEY_OF_NON_EXITING_RULE = RuleKey.of("some_rep", "some_key");
  57. private static final RuleKey AC_RULE_KEY = RuleKey.of("a", "c");
  58. private static final String AC_RULE_UUID = "uuid-684";
  59. private static final String ORGANIZATION_UUID = "org-1";
  60. private static final String QUALITY_GATE_UUID = "QUALITY_GATE_UUID";
  61. @org.junit.Rule
  62. public ExpectedException expectedException = ExpectedException.none();
  63. @org.junit.Rule
  64. public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule()
  65. .setOrganizationUuid(ORGANIZATION_UUID, QUALITY_GATE_UUID);
  66. @org.junit.Rule
  67. public DbTester db = DbTester.create(System2.INSTANCE);
  68. private DbClient dbClient = mock(DbClient.class);
  69. private DbSession dbSession = mock(DbSession.class);
  70. private RuleDao ruleDao = mock(RuleDao.class);
  71. private RuleIndexer ruleIndexer = mock(RuleIndexer.class);
  72. private AdHocRuleCreator adHocRuleCreator = new AdHocRuleCreator(db.getDbClient(), System2.INSTANCE, ruleIndexer, new SequenceUuidFactory());
  73. private RuleRepositoryImpl underTest = new RuleRepositoryImpl(adHocRuleCreator, dbClient, analysisMetadataHolder);
  74. @Before
  75. public void setUp() {
  76. when(dbClient.openSession(anyBoolean())).thenReturn(dbSession);
  77. when(dbClient.ruleDao()).thenReturn(ruleDao);
  78. when(ruleDao.selectAll(any(DbSession.class), eq(ORGANIZATION_UUID))).thenReturn(ImmutableList.of(AB_RULE));
  79. DeprecatedRuleKeyDto abDeprecatedRuleKey1 = deprecatedRuleKeyOf(AB_RULE, AB_RULE_DEPRECATED_KEY_1);
  80. DeprecatedRuleKeyDto abDeprecatedRuleKey2 = deprecatedRuleKeyOf(AB_RULE, AB_RULE_DEPRECATED_KEY_2);
  81. DeprecatedRuleKeyDto deprecatedRuleOfNonExistingRule = deprecatedRuleKeyOf("unknown-rule-uuid", DEPRECATED_KEY_OF_NON_EXITING_RULE);
  82. when(ruleDao.selectAllDeprecatedRuleKeys(any(DbSession.class))).thenReturn(ImmutableSet.of(
  83. abDeprecatedRuleKey1, abDeprecatedRuleKey2, deprecatedRuleOfNonExistingRule));
  84. }
  85. private static DeprecatedRuleKeyDto deprecatedRuleKeyOf(RuleDto ruleDto, RuleKey deprecatedRuleKey) {
  86. return deprecatedRuleKeyOf(ruleDto.getUuid(), deprecatedRuleKey);
  87. }
  88. private static DeprecatedRuleKeyDto deprecatedRuleKeyOf(String ruleUuid, RuleKey deprecatedRuleKey) {
  89. return new DeprecatedRuleKeyDto().setRuleUuid(ruleUuid)
  90. .setOldRepositoryKey(deprecatedRuleKey.repository())
  91. .setOldRuleKey(deprecatedRuleKey.rule());
  92. }
  93. @Test
  94. public void constructor_does_not_query_DB_to_retrieve_rules() {
  95. verifyNoMoreInteractions(dbClient);
  96. }
  97. @Test
  98. public void first_call_to_getByKey_triggers_call_to_db_and_any_subsequent_get_or_find_call_does_not() {
  99. underTest.getByKey(AB_RULE.getKey());
  100. verify(ruleDao, times(1)).selectAll(any(DbSession.class), eq(ORGANIZATION_UUID));
  101. verifyNoMethodCallTriggersCallToDB();
  102. }
  103. @Test
  104. public void first_call_to_findByKey_triggers_call_to_db_and_any_subsequent_get_or_find_call_does_not() {
  105. underTest.findByKey(AB_RULE.getKey());
  106. verify(ruleDao, times(1)).selectAll(any(DbSession.class), eq(ORGANIZATION_UUID));
  107. verifyNoMethodCallTriggersCallToDB();
  108. }
  109. @Test
  110. public void first_call_to_getById_triggers_call_to_db_and_any_subsequent_get_or_find_call_does_not() {
  111. underTest.getByUuid(AB_RULE.getUuid());
  112. verify(ruleDao, times(1)).selectAll(any(DbSession.class), eq(ORGANIZATION_UUID));
  113. verifyNoMethodCallTriggersCallToDB();
  114. }
  115. @Test
  116. public void first_call_to_findById_triggers_call_to_db_and_any_subsequent_get_or_find_call_does_not() {
  117. underTest.findByUuid(AB_RULE.getUuid());
  118. verify(ruleDao, times(1)).selectAll(any(DbSession.class), eq(ORGANIZATION_UUID));
  119. verifyNoMethodCallTriggersCallToDB();
  120. }
  121. @Test
  122. public void getByKey_throws_NPE_if_key_argument_is_null() {
  123. expectNullRuleKeyNPE();
  124. underTest.getByKey(null);
  125. }
  126. @Test
  127. public void getByKey_does_not_call_DB_if_key_argument_is_null() {
  128. try {
  129. underTest.getByKey(null);
  130. } catch (NullPointerException e) {
  131. assertNoCallToDb();
  132. }
  133. }
  134. @Test
  135. public void getByKey_returns_Rule_if_it_exists_in_DB() {
  136. Rule rule = underTest.getByKey(AB_RULE.getKey());
  137. assertIsABRule(rule);
  138. }
  139. @Test
  140. public void getByKey_returns_Rule_if_argument_is_deprecated_key_in_DB_of_rule_in_DB() {
  141. Rule rule = underTest.getByKey(AB_RULE_DEPRECATED_KEY_1);
  142. assertIsABRule(rule);
  143. }
  144. @Test
  145. public void getByKey_throws_IAE_if_rules_does_not_exist_in_DB() {
  146. expectIAERuleNotFound(AC_RULE_KEY);
  147. underTest.getByKey(AC_RULE_KEY);
  148. }
  149. @Test
  150. public void getByKey_throws_IAE_if_argument_is_deprecated_key_in_DB_of_non_existing_rule() {
  151. expectIAERuleNotFound(DEPRECATED_KEY_OF_NON_EXITING_RULE);
  152. underTest.getByKey(DEPRECATED_KEY_OF_NON_EXITING_RULE);
  153. }
  154. private void expectIAERuleNotFound(RuleKey ruleKey) {
  155. expectedException.expect(IllegalArgumentException.class);
  156. expectedException.expectMessage("Can not find rule for key " + ruleKey.toString() + ". This rule does not exist in DB");
  157. }
  158. @Test
  159. public void findByKey_throws_NPE_if_key_argument_is_null() {
  160. expectNullRuleKeyNPE();
  161. underTest.findByKey(null);
  162. }
  163. @Test
  164. public void findByKey_does_not_call_DB_if_key_argument_is_null() {
  165. try {
  166. underTest.findByKey(null);
  167. } catch (NullPointerException e) {
  168. assertNoCallToDb();
  169. }
  170. }
  171. @Test
  172. public void findByKey_returns_absent_if_rule_does_not_exist_in_DB() {
  173. Optional<Rule> rule = underTest.findByKey(AC_RULE_KEY);
  174. assertThat(rule).isEmpty();
  175. }
  176. @Test
  177. public void findByKey_returns_Rule_if_it_exists_in_DB() {
  178. Optional<Rule> rule = underTest.findByKey(AB_RULE.getKey());
  179. assertIsABRule(rule.get());
  180. }
  181. @Test
  182. public void findByKey_returns_Rule_if_argument_is_deprecated_key_in_DB_of_rule_in_DB() {
  183. Optional<Rule> rule = underTest.findByKey(AB_RULE_DEPRECATED_KEY_1);
  184. assertIsABRule(rule.get());
  185. }
  186. @Test
  187. public void findByKey_returns_empty_if_argument_is_deprecated_key_in_DB_of_rule_in_DB() {
  188. Optional<Rule> rule = underTest.findByKey(DEPRECATED_KEY_OF_NON_EXITING_RULE);
  189. assertThat(rule).isEmpty();
  190. }
  191. @Test
  192. public void getByUuid_returns_Rule_if_it_exists_in_DB() {
  193. Rule rule = underTest.getByUuid(AB_RULE.getUuid());
  194. assertIsABRule(rule);
  195. }
  196. @Test
  197. public void getByUuid_throws_IAE_if_rules_does_not_exist_in_DB() {
  198. expectedException.expect(IllegalArgumentException.class);
  199. expectedException.expectMessage("Can not find rule for uuid " + AC_RULE_UUID + ". This rule does not exist in DB");
  200. underTest.getByUuid(AC_RULE_UUID);
  201. }
  202. @Test
  203. public void findByUuid_returns_absent_if_rule_does_not_exist_in_DB() {
  204. Optional<Rule> rule = underTest.findByUuid(AC_RULE_UUID);
  205. assertThat(rule).isEmpty();
  206. }
  207. @Test
  208. public void findByUuid_returns_Rule_if_it_exists_in_DB() {
  209. Optional<Rule> rule = underTest.findByUuid(AB_RULE.getUuid());
  210. assertIsABRule(rule.get());
  211. }
  212. @Test
  213. public void accept_new_externally_defined_Rules() {
  214. RuleKey ruleKey = RuleKey.of("external_eslint", "no-cond-assign");
  215. underTest.addOrUpdateAddHocRuleIfNeeded(ruleKey, () -> new NewAdHocRule(ScannerReport.ExternalIssue.newBuilder().setEngineId("eslint").setRuleId("no-cond-assign").build()));
  216. assertThat(underTest.getByKey(ruleKey)).isNotNull();
  217. assertThat(underTest.getByKey(ruleKey).getType()).isNull();
  218. RuleDao ruleDao = dbClient.ruleDao();
  219. Optional<RuleDefinitionDto> ruleDefinitionDto = ruleDao.selectDefinitionByKey(dbClient.openSession(false), ruleKey);
  220. assertThat(ruleDefinitionDto).isNotPresent();
  221. }
  222. @Test
  223. public void persist_new_externally_defined_Rules() {
  224. underTest = new RuleRepositoryImpl(adHocRuleCreator, db.getDbClient(), analysisMetadataHolder);
  225. RuleKey ruleKey = RuleKey.of("external_eslint", "no-cond-assign");
  226. underTest.addOrUpdateAddHocRuleIfNeeded(ruleKey, () -> new NewAdHocRule(ScannerReport.ExternalIssue.newBuilder().setEngineId("eslint").setRuleId("no-cond-assign").build()));
  227. underTest.saveOrUpdateAddHocRules(db.getSession());
  228. db.commit();
  229. Optional<RuleDefinitionDto> ruleDefinitionDto = db.getDbClient().ruleDao().selectDefinitionByKey(db.getSession(), ruleKey);
  230. assertThat(ruleDefinitionDto).isPresent();
  231. Rule rule = underTest.getByKey(ruleKey);
  232. assertThat(rule).isNotNull();
  233. assertThat(underTest.getByUuid(ruleDefinitionDto.get().getUuid())).isNotNull();
  234. verify(ruleIndexer).commitAndIndex(db.getSession(), ruleDefinitionDto.get().getUuid());
  235. }
  236. private void expectNullRuleKeyNPE() {
  237. expectedException.expect(NullPointerException.class);
  238. expectedException.expectMessage("RuleKey can not be null");
  239. }
  240. private void verifyNoMethodCallTriggersCallToDB() {
  241. reset(ruleDao);
  242. underTest.getByKey(AB_RULE.getKey());
  243. assertNoCallToDb();
  244. reset(ruleDao);
  245. underTest.findByKey(AB_RULE.getKey());
  246. assertNoCallToDb();
  247. reset(ruleDao);
  248. underTest.getByUuid(AB_RULE.getUuid());
  249. assertNoCallToDb();
  250. reset(ruleDao);
  251. underTest.findByUuid(AB_RULE.getUuid());
  252. assertNoCallToDb();
  253. }
  254. private void assertNoCallToDb() {
  255. verifyNoMoreInteractions(ruleDao);
  256. }
  257. private void assertIsABRule(Rule rule) {
  258. assertThat(rule).isNotNull();
  259. assertThat(rule.getUuid()).isEqualTo(AB_RULE.getUuid());
  260. assertThat(rule.getKey()).isEqualTo(AB_RULE.getKey());
  261. assertThat(rule.getRemediationFunction()).isNull();
  262. assertThat(rule.getStatus()).isEqualTo(RuleStatus.REMOVED);
  263. }
  264. private static RuleDto createABRuleDto() {
  265. RuleKey ruleKey = RuleKey.of("a", "b");
  266. return new RuleDto()
  267. .setRepositoryKey(ruleKey.repository())
  268. .setRuleKey(ruleKey.rule())
  269. .setStatus(RuleStatus.REMOVED)
  270. .setType(RuleType.CODE_SMELL);
  271. }
  272. }