]> source.dussan.org Git - sonarqube.git/blob
d036d47eea0ddb167a1db5be09ab84909a3ce334
[sonarqube.git] /
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.server.issue.index;
21
22 import com.tngtech.java.junit.dataprovider.DataProvider;
23 import com.tngtech.java.junit.dataprovider.DataProviderRunner;
24 import com.tngtech.java.junit.dataprovider.UseDataProvider;
25 import java.util.Arrays;
26 import java.util.Collections;
27 import java.util.List;
28 import java.util.stream.IntStream;
29 import org.junit.Rule;
30 import org.junit.Test;
31 import org.junit.runner.RunWith;
32 import org.sonar.api.utils.System2;
33 import org.sonar.db.DbSession;
34 import org.sonar.db.DbTester;
35 import org.sonar.db.component.ComponentDto;
36 import org.sonar.db.project.ProjectDto;
37 import org.sonar.server.es.EsIndexSyncInProgressException;
38
39 import static java.util.Collections.singletonList;
40 import static org.assertj.core.api.Assertions.assertThat;
41 import static org.assertj.core.api.Assertions.assertThatThrownBy;
42
43 @RunWith(DataProviderRunner.class)
44 public class IssueIndexSyncProgressCheckerTest {
45
46   @Rule
47   public DbTester db = DbTester.create(System2.INSTANCE);
48
49   private IssueIndexSyncProgressChecker underTest = new IssueIndexSyncProgressChecker(db.getDbClient());
50
51   @Test
52   public void return_100_if_there_is_no_tasks_left() {
53     IssueSyncProgress issueSyncProgress = underTest.getIssueSyncProgress(db.getSession());
54     assertThat(issueSyncProgress.getCompleted()).isZero();
55     assertThat(issueSyncProgress.getTotal()).isZero();
56     assertThat(issueSyncProgress.toPercentCompleted()).isEqualTo(100);
57     assertThat(issueSyncProgress.isCompleted()).isTrue();
58   }
59
60   @Test
61   public void return_100_if_all_branches_have_need_issue_sync_set_FALSE() {
62     IntStream.range(0, 13).forEach(value -> insertProjectWithBranches(false, 2));
63     IntStream.range(0, 14).forEach(value -> insertProjectWithBranches(false, 4));
64     IntStream.range(0, 4).forEach(value -> insertProjectWithBranches(false, 10));
65
66     IssueSyncProgress result = underTest.getIssueSyncProgress(db.getSession());
67     assertThat(result.getCompleted()).isEqualTo(153);
68     assertThat(result.getTotal()).isEqualTo(153);
69     assertThat(result.toPercentCompleted()).isEqualTo(100);
70     assertThat(result.isCompleted()).isTrue();
71   }
72
73   @Test
74   @UseDataProvider("various_task_numbers")
75   public void return_correct_percent_value_for_branches_to_sync(int toSync, int synced, int expectedPercent, boolean isCompleted) {
76     IntStream.range(0, toSync).forEach(value -> insertProjectWithBranches(true, 0));
77     IntStream.range(0, synced).forEach(value -> insertProjectWithBranches(false, 0));
78
79     IssueSyncProgress result = underTest.getIssueSyncProgress(db.getSession());
80     assertThat(result.getCompleted()).isEqualTo(synced);
81     assertThat(result.getTotal()).isEqualTo(toSync + synced);
82     assertThat(result.toPercentCompleted()).isEqualTo(expectedPercent);
83     assertThat(result.isCompleted()).isEqualTo(isCompleted);
84   }
85
86   @DataProvider
87   public static Object[][] various_task_numbers() {
88     return new Object[][] {
89       // toSync, synced, expected result, expectedCompleted
90       {0, 0, 100, true},
91       {0, 9, 100, true},
92       {10, 0, 0, false},
93       {99, 1, 1, false},
94       {2, 1, 33, false},
95       {6, 4, 40, false},
96       {7, 7, 50, false},
97       {1, 2, 66, false},
98       {4, 10, 71, false},
99       {1, 99, 99, false},
100     };
101   }
102
103   @Test
104   public void return_0_if_all_branches_have_need_issue_sync_set_TRUE() {
105     // only project
106     IntStream.range(0, 10).forEach(value -> insertProjectWithBranches(true, 0));
107
108     // project + additional branch
109     IntStream.range(0, 10).forEach(value -> insertProjectWithBranches(true, 1));
110
111     IssueSyncProgress result = underTest.getIssueSyncProgress(db.getSession());
112     assertThat(result.getCompleted()).isZero();
113     assertThat(result.getTotal()).isEqualTo(30);
114     assertThat(result.toPercentCompleted()).isZero();
115     assertThat(result.isCompleted()).isFalse();
116   }
117
118   @Test
119   public void checkIfAnyComponentsIssueSyncInProgress_throws_exception_if_all_components_have_need_issue_sync_TRUE() {
120     ProjectDto projectDto1 = insertProjectWithBranches(true, 0);
121     ProjectDto projectDto2 = insertProjectWithBranches(true, 0);
122     DbSession session = db.getSession();
123     List<String> projectKeys = Arrays.asList(projectDto1.getKey(), projectDto2.getKey());
124     assertThatThrownBy(() -> underTest.checkIfAnyComponentsIssueSyncInProgress(session, projectKeys, null, null))
125       .isInstanceOf(EsIndexSyncInProgressException.class)
126       .hasFieldOrPropertyWithValue("httpCode", 503)
127       .hasMessage("Results are temporarily unavailable. Indexing of issues is in progress.");
128   }
129
130   @Test
131   public void checkIfAnyComponentsIssueSyncInProgress_does_not_throw_exception_if_all_components_have_need_issue_sync_FALSE() {
132     underTest.checkIfAnyComponentsIssueSyncInProgress(db.getSession(), Collections.emptyList(), null, null);
133     ProjectDto projectDto1 = insertProjectWithBranches(false, 0);
134     ProjectDto projectDto2 = insertProjectWithBranches(false, 0);
135     underTest.checkIfAnyComponentsIssueSyncInProgress(db.getSession(), Arrays.asList(projectDto1.getKey(), projectDto2.getKey()), null, null);
136   }
137
138   @Test
139   public void checkIfAnyComponentsIssueSyncInProgress_throws_exception_if_at_least_one_component_has_need_issue_sync_TRUE() {
140     ProjectDto projectDto1 = insertProjectWithBranches(false, 0);
141     ProjectDto projectDto2 = insertProjectWithBranches(true, 0);
142
143     DbSession session = db.getSession();
144     List<String> projectKeys = Arrays.asList(projectDto1.getKey(), projectDto2.getKey());
145     assertThatThrownBy(() -> underTest.checkIfAnyComponentsIssueSyncInProgress(session, projectKeys, null, null))
146       .isInstanceOf(EsIndexSyncInProgressException.class)
147       .hasFieldOrPropertyWithValue("httpCode", 503)
148       .hasMessage("Results are temporarily unavailable. Indexing of issues is in progress.");
149   }
150
151   @Test
152   public void checkIfAnyComponentsIssueSyncInProgress_single_component() {
153     ProjectDto projectDto1 = insertProjectWithBranches(true, 0);
154     ProjectDto projectDto2 = insertProjectWithBranches(false, 0);
155
156     DbSession session = db.getSession();
157     List<String> projectKey1 = singletonList(projectDto2.getKey());
158     // do nothing when need issue sync false
159     underTest.checkIfAnyComponentsIssueSyncInProgress(session, projectKey1, null, null);
160
161     List<String> projectKey2 = singletonList(projectDto1.getKey());
162     // throws if flag set to TRUE
163     assertThatThrownBy(() -> underTest.checkIfAnyComponentsIssueSyncInProgress(session,
164         projectKey2, null, null))
165         .isInstanceOf(EsIndexSyncInProgressException.class)
166         .hasFieldOrPropertyWithValue("httpCode", 503)
167         .hasMessage("Results are temporarily unavailable. Indexing of issues is in progress.");
168   }
169
170   @Test
171   public void checkIfAnyComponentsNeedIssueSync_single_view_subview_or_app() {
172     ProjectDto projectDto1 = insertProjectWithBranches(true, 0);
173
174     ComponentDto app = db.components().insertPublicApplication();
175     ComponentDto view = db.components().insertPrivatePortfolio();
176     ComponentDto subview = db.components().insertSubView(view);
177
178     DbSession session = db.getSession();
179     List<String> appViewOrSubviewKeys = Arrays.asList(projectDto1.getKey(), app.getDbKey(), view.getDbKey(), subview.getDbKey());
180
181     // throws if flag set to TRUE
182     assertThatThrownBy(() -> underTest.checkIfAnyComponentsIssueSyncInProgress(session,
183       appViewOrSubviewKeys, null, null))
184         .isInstanceOf(EsIndexSyncInProgressException.class)
185         .hasFieldOrPropertyWithValue("httpCode", 503)
186         .hasMessage("Results are temporarily unavailable. Indexing of issues is in progress.");
187   }
188
189   @Test
190   public void checkIfIssueSyncInProgress_throws_exception_if_at_least_one_component_has_need_issue_sync_TRUE() {
191     insertProjectWithBranches(false, 0);
192     underTest.checkIfIssueSyncInProgress(db.getSession());
193     insertProjectWithBranches(true, 0);
194
195     DbSession session = db.getSession();
196     assertThatThrownBy(() -> underTest.checkIfIssueSyncInProgress(session))
197       .isInstanceOf(EsIndexSyncInProgressException.class)
198       .hasFieldOrPropertyWithValue("httpCode", 503)
199       .hasMessage("Results are temporarily unavailable. Indexing of issues is in progress.");
200   }
201
202   @Test
203   public void doProjectNeedIssueSync() {
204     ProjectDto projectDto1 = insertProjectWithBranches(false, 0);
205     assertThat(underTest.doProjectNeedIssueSync(db.getSession(), projectDto1.getUuid())).isFalse();
206     ProjectDto projectDto2 = insertProjectWithBranches(true, 0);
207     assertThat(underTest.doProjectNeedIssueSync(db.getSession(), projectDto2.getUuid())).isTrue();
208   }
209
210   @Test
211   public void findProjectUuidsWithIssuesSyncNeed() {
212     ProjectDto projectDto1 = insertProjectWithBranches(false, 0);
213     ProjectDto projectDto2 = insertProjectWithBranches(false, 0);
214     ProjectDto projectDto3 = insertProjectWithBranches(true, 0);
215     ProjectDto projectDto4 = insertProjectWithBranches(true, 0);
216
217     assertThat(underTest.findProjectUuidsWithIssuesSyncNeed(db.getSession(),
218       Arrays.asList(projectDto1.getUuid(), projectDto2.getUuid(), projectDto3.getUuid(), projectDto4.getUuid())))
219         .containsOnly(projectDto3.getUuid(), projectDto4.getUuid());
220   }
221
222   private ProjectDto insertProjectWithBranches(boolean needIssueSync, int numberOfBranches) {
223     ProjectDto projectDto = db.components()
224       .insertPrivateProjectDto(db.getDefaultOrganization(), branchDto -> branchDto.setNeedIssueSync(needIssueSync));
225     IntStream.range(0, numberOfBranches).forEach(
226       i -> db.components().insertProjectBranch(projectDto, branchDto -> branchDto.setNeedIssueSync(needIssueSync)));
227     return projectDto;
228   }
229 }