3 * Copyright (C) 2009-2020 SonarSource SA
4 * mailto:info AT sonarsource DOT com
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.
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.
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.
20 package org.sonar.server.issue.index;
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;
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;
43 @RunWith(DataProviderRunner.class)
44 public class IssueIndexSyncProgressCheckerTest {
47 public DbTester db = DbTester.create(System2.INSTANCE);
49 private IssueIndexSyncProgressChecker underTest = new IssueIndexSyncProgressChecker(db.getDbClient());
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();
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));
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();
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));
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);
87 public static Object[][] various_task_numbers() {
88 return new Object[][] {
89 // toSync, synced, expected result, expectedCompleted
104 public void return_0_if_all_branches_have_need_issue_sync_set_TRUE() {
106 IntStream.range(0, 10).forEach(value -> insertProjectWithBranches(true, 0));
108 // project + additional branch
109 IntStream.range(0, 10).forEach(value -> insertProjectWithBranches(true, 1));
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();
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.");
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);
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);
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.");
152 public void checkIfAnyComponentsIssueSyncInProgress_single_component() {
153 ProjectDto projectDto1 = insertProjectWithBranches(true, 0);
154 ProjectDto projectDto2 = insertProjectWithBranches(false, 0);
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);
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.");
171 public void checkIfAnyComponentsNeedIssueSync_single_view_subview_or_app() {
172 ProjectDto projectDto1 = insertProjectWithBranches(true, 0);
174 ComponentDto app = db.components().insertPublicApplication();
175 ComponentDto view = db.components().insertPrivatePortfolio();
176 ComponentDto subview = db.components().insertSubView(view);
178 DbSession session = db.getSession();
179 List<String> appViewOrSubviewKeys = Arrays.asList(projectDto1.getKey(), app.getDbKey(), view.getDbKey(), subview.getDbKey());
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.");
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);
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.");
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();
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);
217 assertThat(underTest.findProjectUuidsWithIssuesSyncNeed(db.getSession(),
218 Arrays.asList(projectDto1.getUuid(), projectDto2.getUuid(), projectDto3.getUuid(), projectDto4.getUuid())))
219 .containsOnly(projectDto3.getUuid(), projectDto4.getUuid());
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)));