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.

ActiveRuleIndexerIT.java 7.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2023 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.index;
  21. import java.util.Collection;
  22. import java.util.Collections;
  23. import java.util.List;
  24. import org.assertj.core.groups.Tuple;
  25. import org.junit.Before;
  26. import org.junit.Rule;
  27. import org.junit.Test;
  28. import org.sonar.api.utils.System2;
  29. import org.sonar.db.DbTester;
  30. import org.sonar.db.es.EsQueueDto;
  31. import org.sonar.db.qualityprofile.ActiveRuleDto;
  32. import org.sonar.db.qualityprofile.QProfileDto;
  33. import org.sonar.db.rule.RuleDto;
  34. import org.sonar.server.es.EsTester;
  35. import org.sonar.server.qualityprofile.ActiveRuleChange;
  36. import static java.util.Arrays.stream;
  37. import static java.util.Collections.emptySet;
  38. import static java.util.Collections.singletonList;
  39. import static org.assertj.core.api.Assertions.assertThat;
  40. import static org.sonar.server.rule.index.RuleIndexDefinition.TYPE_ACTIVE_RULE;
  41. public class ActiveRuleIndexerIT {
  42. private System2 system2 = System2.INSTANCE;
  43. @Rule
  44. public DbTester db = DbTester.create(system2);
  45. @Rule
  46. public EsTester es = EsTester.create();
  47. private ActiveRuleIndexer underTest = new ActiveRuleIndexer(db.getDbClient(), es.client());
  48. private RuleDto rule1;
  49. private RuleDto rule2;
  50. private QProfileDto profile1;
  51. private QProfileDto profile2;
  52. @Before
  53. public void before() {
  54. rule1 = db.rules().insert();
  55. rule2 = db.rules().insert();
  56. profile1 = db.qualityProfiles().insert();
  57. profile2 = db.qualityProfiles().insert();
  58. }
  59. @Test
  60. public void getIndexTypes() {
  61. assertThat(underTest.getIndexTypes()).containsExactly(TYPE_ACTIVE_RULE);
  62. }
  63. @Test
  64. public void indexOnStartup_does_nothing_if_no_data() {
  65. underTest.indexOnStartup(emptySet());
  66. assertThat(es.countDocuments(TYPE_ACTIVE_RULE)).isZero();
  67. }
  68. @Test
  69. public void indexOnStartup_indexes_all_data() {
  70. ActiveRuleDto activeRule = db.qualityProfiles().activateRule(profile1, rule1);
  71. underTest.indexOnStartup(emptySet());
  72. List<ActiveRuleDoc> docs = es.getDocuments(TYPE_ACTIVE_RULE, ActiveRuleDoc.class);
  73. assertThat(docs).hasSize(1);
  74. verify(docs.get(0), profile1, activeRule);
  75. assertThatEsQueueTableIsEmpty();
  76. }
  77. @Test
  78. public void indexAll_indexes_all_data() {
  79. ActiveRuleDto activeRule = db.qualityProfiles().activateRule(profile1, rule1);
  80. underTest.indexAll();
  81. List<ActiveRuleDoc> docs = es.getDocuments(TYPE_ACTIVE_RULE, ActiveRuleDoc.class);
  82. assertThat(docs).hasSize(1);
  83. verify(docs.get(0), profile1, activeRule);
  84. assertThatEsQueueTableIsEmpty();
  85. }
  86. @Test
  87. public void test_commitAndIndex() {
  88. ActiveRuleDto ar1 = db.qualityProfiles().activateRule(profile1, rule1);
  89. ActiveRuleDto ar2 = db.qualityProfiles().activateRule(profile2, rule1);
  90. db.qualityProfiles().activateRule(profile2, rule2);
  91. commitAndIndex(rule1, ar1, ar2);
  92. verifyOnlyIndexed(ar1, ar2);
  93. assertThatEsQueueTableIsEmpty();
  94. }
  95. @Test
  96. public void commitAndIndex_empty_list() {
  97. db.qualityProfiles().activateRule(profile1, rule1);
  98. underTest.commitAndIndex(db.getSession(), Collections.emptyList());
  99. assertThat(es.countDocuments(TYPE_ACTIVE_RULE)).isZero();
  100. assertThatEsQueueTableIsEmpty();
  101. }
  102. @Test
  103. public void commitAndIndex_keeps_elements_to_recover_in_ES_QUEUE_on_errors() {
  104. ActiveRuleDto ar = db.qualityProfiles().activateRule(profile1, rule1);
  105. es.lockWrites(TYPE_ACTIVE_RULE);
  106. commitAndIndex(rule1, ar);
  107. EsQueueDto expectedItem = EsQueueDto.create(TYPE_ACTIVE_RULE.format(), "ar_" + ar.getUuid(), "activeRuleUuid", ar.getRuleUuid());
  108. assertThatEsQueueContainsExactly(expectedItem);
  109. es.unlockWrites(TYPE_ACTIVE_RULE);
  110. }
  111. @Test
  112. public void commitAndIndex_deletes_the_documents_that_dont_exist_in_database() {
  113. ActiveRuleDto ar = db.qualityProfiles().activateRule(profile1, rule1);
  114. indexAll();
  115. assertThat(es.countDocuments(TYPE_ACTIVE_RULE)).isOne();
  116. db.getDbClient().activeRuleDao().delete(db.getSession(), ar.getKey());
  117. commitAndIndex(rule1, ar);
  118. assertThat(es.countDocuments(TYPE_ACTIVE_RULE)).isZero();
  119. assertThatEsQueueTableIsEmpty();
  120. }
  121. @Test
  122. public void index_fails_and_deletes_doc_if_docIdType_is_unsupported() {
  123. EsQueueDto item = EsQueueDto.create(TYPE_ACTIVE_RULE.format(), "the_id", "unsupported", "the_routing");
  124. db.getDbClient().esQueueDao().insert(db.getSession(), item);
  125. underTest.index(db.getSession(), singletonList(item));
  126. assertThatEsQueueTableIsEmpty();
  127. assertThat(es.countDocuments(TYPE_ACTIVE_RULE)).isZero();
  128. }
  129. @Test
  130. public void commitDeletionOfProfiles() {
  131. ActiveRuleDto ar1 = db.qualityProfiles().activateRule(profile1, rule1);
  132. db.qualityProfiles().activateRule(profile2, rule1);
  133. db.qualityProfiles().activateRule(profile2, rule2);
  134. indexAll();
  135. db.getDbClient().qualityProfileDao().deleteRulesProfilesByUuids(db.getSession(), singletonList(profile2.getRulesProfileUuid()));
  136. underTest.commitDeletionOfProfiles(db.getSession(), singletonList(profile2));
  137. verifyOnlyIndexed(ar1);
  138. }
  139. @Test
  140. public void commitDeletionOfProfiles_does_nothing_if_profiles_are_not_indexed() {
  141. db.qualityProfiles().activateRule(profile1, rule1);
  142. indexAll();
  143. assertThat(es.countDocuments(TYPE_ACTIVE_RULE)).isOne();
  144. underTest.commitDeletionOfProfiles(db.getSession(), singletonList(profile2));
  145. assertThat(es.countDocuments(TYPE_ACTIVE_RULE)).isOne();
  146. }
  147. private void assertThatEsQueueTableIsEmpty() {
  148. assertThat(db.countRowsOfTable(db.getSession(), "es_queue")).isZero();
  149. }
  150. private void assertThatEsQueueContainsExactly(EsQueueDto expected) {
  151. Collection<EsQueueDto> items = db.getDbClient().esQueueDao().selectForRecovery(db.getSession(), system2.now() + 1_000, 10);
  152. assertThat(items)
  153. .extracting(EsQueueDto::getDocId, EsQueueDto::getDocIdType, EsQueueDto::getDocRouting)
  154. .containsExactlyInAnyOrder(Tuple.tuple(expected.getDocId(), expected.getDocIdType(), expected.getDocRouting()));
  155. }
  156. private void commitAndIndex(RuleDto rule, ActiveRuleDto... ar) {
  157. underTest.commitAndIndex(db.getSession(), stream(ar)
  158. .map(a -> new ActiveRuleChange(ActiveRuleChange.Type.ACTIVATED, a, rule))
  159. .toList());
  160. }
  161. private void verifyOnlyIndexed(ActiveRuleDto... expected) {
  162. List<String> docs = es.getIds(TYPE_ACTIVE_RULE);
  163. assertThat(docs).hasSize(expected.length);
  164. for (ActiveRuleDto activeRuleDto : expected) {
  165. assertThat(docs).contains("ar_" + activeRuleDto.getUuid());
  166. }
  167. }
  168. private void verify(ActiveRuleDoc doc1, QProfileDto profile, ActiveRuleDto activeRule) {
  169. assertThat(doc1)
  170. .matches(doc -> doc.getId().equals("ar_" + activeRule.getUuid()))
  171. .matches(doc -> doc.getRuleProfileUuid().equals(profile.getRulesProfileUuid()))
  172. .matches(doc -> doc.getSeverity().equals(activeRule.getSeverityString()));
  173. }
  174. private void indexAll() {
  175. underTest.indexOnStartup(emptySet());
  176. }
  177. }