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.ce.task.projectanalysis.component;
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.Optional;
26 import javax.annotation.Nullable;
27 import org.junit.Rule;
28 import org.junit.Test;
29 import org.junit.rules.ExpectedException;
30 import org.junit.runner.RunWith;
31 import org.sonar.api.config.Configuration;
32 import org.sonar.api.utils.System2;
33 import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
34 import org.sonar.ce.task.projectanalysis.analysis.Branch;
35 import org.sonar.db.DbTester;
36 import org.sonar.db.component.BranchDto;
37 import org.sonar.db.component.BranchType;
38 import org.sonar.db.component.ComponentDto;
39 import org.sonar.db.component.ComponentTesting;
40 import org.sonar.db.protobuf.DbProjectBranches;
41 import org.sonar.server.project.Project;
43 import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
44 import static org.assertj.core.api.Assertions.assertThat;
45 import static org.mockito.Mockito.mock;
46 import static org.mockito.Mockito.when;
47 import static org.sonar.ce.task.projectanalysis.component.Component.Type.PROJECT;
48 import static org.sonar.ce.task.projectanalysis.component.ReportComponent.builder;
49 import static org.sonar.core.config.PurgeConstants.BRANCHES_TO_KEEP_WHEN_INACTIVE;
50 import static org.sonar.db.component.BranchType.BRANCH;
51 import static org.sonar.db.component.BranchType.PULL_REQUEST;
53 @RunWith(DataProviderRunner.class)
54 public class BranchPersisterImplTest {
55 private final static Component MAIN = builder(PROJECT, 1).setUuid("PROJECT_UUID").setKey("PROJECT_KEY").build();
56 private final static Component BRANCH1 = builder(PROJECT, 1).setUuid("BRANCH_UUID").setKey("BRANCH_KEY").build();
59 public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule();
61 public DbTester dbTester = DbTester.create(System2.INSTANCE);
63 public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule();
65 public ExpectedException exception = ExpectedException.none();
67 private Configuration configuration = mock(Configuration.class);
69 private BranchPersister underTest = new BranchPersisterImpl(dbTester.getDbClient(), treeRootHolder, analysisMetadataHolder, configuration);
72 public void persist_fails_with_ISE_if_no_component_for_main_branches() {
73 analysisMetadataHolder.setBranch(createBranch(BRANCH, true, "master"));
74 treeRootHolder.setRoot(MAIN);
76 expectMissingComponentISE();
78 underTest.persist(dbTester.getSession());
82 public void persist_fails_with_ISE_if_no_component_for_branches() {
83 analysisMetadataHolder.setBranch(createBranch(BRANCH, false, "foo"));
84 treeRootHolder.setRoot(BRANCH1);
86 expectMissingComponentISE();
88 underTest.persist(dbTester.getSession());
92 public void persist_fails_with_ISE_if_no_component_for_pull_request() {
93 analysisMetadataHolder.setBranch(createBranch(BranchType.PULL_REQUEST, false, "12"));
94 treeRootHolder.setRoot(BRANCH1);
96 expectMissingComponentISE();
98 underTest.persist(dbTester.getSession());
102 @UseDataProvider("nullOrNotNullString")
103 public void persist_creates_row_in_PROJECTS_BRANCHES_for_branch(@Nullable String mergeBranchUuid) {
104 String branchName = "branch";
106 // add project and branch in table PROJECTS
107 ComponentDto mainComponent = ComponentTesting.newPrivateProjectDto(dbTester.organizations().insert(), MAIN.getUuid()).setDbKey(MAIN.getKey());
108 ComponentDto component = ComponentTesting.newBranchComponent(mainComponent, new BranchDto().setUuid(BRANCH1.getUuid()).setKey(BRANCH1.getKey()).setBranchType(BRANCH));
109 dbTester.getDbClient().componentDao().insert(dbTester.getSession(), mainComponent, component);
111 // set project in metadata
112 treeRootHolder.setRoot(BRANCH1);
113 analysisMetadataHolder.setBranch(createBranch(BRANCH, false, branchName, mergeBranchUuid));
114 analysisMetadataHolder.setProject(Project.from(mainComponent));
116 underTest.persist(dbTester.getSession());
118 dbTester.getSession().commit();
120 assertThat(dbTester.countRowsOfTable("components")).isEqualTo(2);
121 Optional<BranchDto> branchDto = dbTester.getDbClient().branchDao().selectByUuid(dbTester.getSession(), BRANCH1.getUuid());
122 assertThat(branchDto).isPresent();
123 assertThat(branchDto.get().getBranchType()).isEqualTo(BRANCH);
124 assertThat(branchDto.get().getKey()).isEqualTo(branchName);
125 assertThat(branchDto.get().getMergeBranchUuid()).isEqualTo(mergeBranchUuid);
126 assertThat(branchDto.get().getProjectUuid()).isEqualTo(MAIN.getUuid());
127 assertThat(branchDto.get().getPullRequestData()).isNull();
131 public void main_branch_is_excluded_from_branch_purge_by_default() {
132 analysisMetadataHolder.setBranch(createBranch(BRANCH, true, "master"));
133 treeRootHolder.setRoot(MAIN);
134 dbTester.components().insertPublicProject(p -> p.setDbKey(MAIN.getDbKey()).setUuid(MAIN.getUuid()));
137 underTest.persist(dbTester.getSession());
139 Optional<BranchDto> branchDto = dbTester.getDbClient().branchDao().selectByUuid(dbTester.getSession(), MAIN.getUuid());
140 assertThat(branchDto.get().isExcludeFromPurge()).isTrue();
144 public void non_main_branch_is_excluded_from_branch_purge_if_matches_sonar_dbcleaner_keepFromPurge_property() {
145 when(configuration.getStringArray(BRANCHES_TO_KEEP_WHEN_INACTIVE)).thenReturn(new String[] {"BRANCH.*"});
147 analysisMetadataHolder.setBranch(createBranch(BRANCH, false, "BRANCH_KEY"));
148 treeRootHolder.setRoot(BRANCH1);
149 ComponentDto mainComponent = dbTester.components().insertPublicProject(p -> p.setDbKey(MAIN.getDbKey()).setUuid(MAIN.getUuid()));
150 ComponentDto component = ComponentTesting.newBranchComponent(mainComponent, new BranchDto().setUuid(BRANCH1.getUuid()).setKey(BRANCH1.getKey()).setBranchType(BRANCH));
151 dbTester.getDbClient().componentDao().insert(dbTester.getSession(), component);
154 underTest.persist(dbTester.getSession());
156 Optional<BranchDto> branchDto = dbTester.getDbClient().branchDao().selectByUuid(dbTester.getSession(), BRANCH1.getUuid());
157 assertThat(branchDto.get().isExcludeFromPurge()).isTrue();
161 public void non_main_branch_is_included_in_branch_purge_if_branch_name_does_not_match_sonar_dbcleaner_keepFromPurge_property() {
162 when(configuration.getStringArray(BRANCHES_TO_KEEP_WHEN_INACTIVE)).thenReturn(new String[] {"foobar-.*"});
164 analysisMetadataHolder.setBranch(createBranch(BRANCH, false, "BRANCH_KEY"));
165 treeRootHolder.setRoot(BRANCH1);
166 ComponentDto mainComponent = dbTester.components().insertPublicProject(p -> p.setDbKey(MAIN.getDbKey()).setUuid(MAIN.getUuid()));
167 ComponentDto component = ComponentTesting.newBranchComponent(mainComponent, new BranchDto().setUuid(BRANCH1.getUuid()).setKey(BRANCH1.getKey()).setBranchType(BRANCH));
168 dbTester.getDbClient().componentDao().insert(dbTester.getSession(), component);
171 underTest.persist(dbTester.getSession());
173 Optional<BranchDto> branchDto = dbTester.getDbClient().branchDao().selectByUuid(dbTester.getSession(), BRANCH1.getUuid());
174 assertThat(branchDto.get().isExcludeFromPurge()).isFalse();
178 public static Object[][] nullOrNotNullString() {
179 return new Object[][] {
181 {randomAlphabetic(12)}
186 public void persist_creates_row_in_PROJECTS_BRANCHES_for_pull_request() {
187 String pullRequestId = "pr-123";
189 // add project and branch in table PROJECTS
190 ComponentDto mainComponent = ComponentTesting.newPrivateProjectDto(dbTester.organizations().insert(), MAIN.getUuid()).setDbKey(MAIN.getKey());
191 ComponentDto component = ComponentTesting.newBranchComponent(mainComponent, new BranchDto().setUuid(BRANCH1.getUuid()).setKey(BRANCH1.getKey()).setBranchType(PULL_REQUEST));
192 dbTester.getDbClient().componentDao().insert(dbTester.getSession(), mainComponent, component);
194 // set project in metadata
195 treeRootHolder.setRoot(BRANCH1);
196 analysisMetadataHolder.setBranch(createBranch(PULL_REQUEST, false, pullRequestId, "mergeBanchUuid"));
197 analysisMetadataHolder.setProject(Project.from(mainComponent));
198 analysisMetadataHolder.setPullRequestKey(pullRequestId);
200 underTest.persist(dbTester.getSession());
202 dbTester.getSession().commit();
204 assertThat(dbTester.countRowsOfTable("components")).isEqualTo(2);
205 Optional<BranchDto> branchDto = dbTester.getDbClient().branchDao().selectByUuid(dbTester.getSession(), BRANCH1.getUuid());
206 assertThat(branchDto).isPresent();
207 assertThat(branchDto.get().getBranchType()).isEqualTo(PULL_REQUEST);
208 assertThat(branchDto.get().getKey()).isEqualTo(pullRequestId);
209 assertThat(branchDto.get().getMergeBranchUuid()).isEqualTo("mergeBanchUuid");
210 assertThat(branchDto.get().getProjectUuid()).isEqualTo(MAIN.getUuid());
211 assertThat(branchDto.get().getPullRequestData()).isEqualTo(DbProjectBranches.PullRequestData.newBuilder()
212 .setBranch(pullRequestId)
213 .setTarget("mergeBanchUuid")
214 .setTitle(pullRequestId)
218 private static Branch createBranch(BranchType type, boolean isMain, String name) {
219 return createBranch(type, isMain, name, null);
222 private static Branch createBranch(BranchType type, boolean isMain, String name, @Nullable String mergeBranchUuid) {
223 Branch branch = mock(Branch.class);
224 when(branch.getType()).thenReturn(type);
225 when(branch.getName()).thenReturn(name);
226 when(branch.isMain()).thenReturn(isMain);
227 when(branch.getReferenceBranchUuid()).thenReturn(mergeBranchUuid);
228 when(branch.getTargetBranchName()).thenReturn(mergeBranchUuid);
232 private void expectMissingComponentISE() {
233 exception.expect(IllegalStateException.class);
234 exception.expectMessage("Component has been deleted by end-user during analysis");