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