]> source.dussan.org Git - sonarqube.git/blob
33e9463a68f7084f3454276e591b5b15fbf4d8ab
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2024 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.ce.task.projectexport.analysis;
21
22 import com.sonarsource.governance.projectdump.protobuf.ProjectDump;
23 import com.tngtech.java.junit.dataprovider.DataProvider;
24 import com.tngtech.java.junit.dataprovider.DataProviderRunner;
25 import com.tngtech.java.junit.dataprovider.UseDataProvider;
26 import java.util.List;
27 import java.util.Set;
28 import javax.annotation.Nullable;
29 import org.junit.Before;
30 import org.junit.Rule;
31 import org.junit.Test;
32 import org.junit.runner.RunWith;
33 import org.slf4j.event.Level;
34 import org.sonar.api.resources.Qualifiers;
35 import org.sonar.api.resources.Scopes;
36 import org.sonar.api.testfixtures.log.LogTester;
37 import org.sonar.api.utils.System2;
38 import org.sonar.ce.task.projectexport.component.ComponentRepositoryImpl;
39 import org.sonar.ce.task.projectexport.steps.DumpElement;
40 import org.sonar.ce.task.projectexport.steps.FakeDumpWriter;
41 import org.sonar.ce.task.projectexport.steps.ProjectHolder;
42 import org.sonar.ce.task.step.TestComputationStepContext;
43 import org.sonar.db.DbTester;
44 import org.sonar.db.component.ComponentDto;
45 import org.sonar.db.component.SnapshotDto;
46
47 import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
48 import static org.apache.commons.lang3.StringUtils.defaultString;
49 import static org.assertj.core.api.Assertions.assertThat;
50 import static org.assertj.core.api.Assertions.assertThatThrownBy;
51 import static org.mockito.Mockito.mock;
52 import static org.mockito.Mockito.when;
53 import static org.sonar.db.component.ComponentDto.UUID_PATH_OF_ROOT;
54 import static org.sonar.db.component.ComponentDto.UUID_PATH_SEPARATOR;
55
56 @RunWith(DataProviderRunner.class)
57 public class ExportAnalysesStepIT {
58
59   private static final String PROJECT_UUID = "PROJECT_UUID";
60   private static final ComponentDto PROJECT = new ComponentDto()
61     // no id yet
62     .setScope(Scopes.PROJECT)
63     .setQualifier(Qualifiers.PROJECT)
64     .setKey("the_project")
65     .setName("The Project")
66     .setDescription("The project description")
67     .setEnabled(true)
68     .setUuid(PROJECT_UUID)
69     .setUuidPath(UUID_PATH_OF_ROOT)
70     .setBranchUuid(PROJECT_UUID);
71
72   private static final String DIR_UUID = "DIR_UUID";
73   private static final String UUID_PATH = UUID_PATH_OF_ROOT + UUID_PATH_SEPARATOR + DIR_UUID;
74   private static final ComponentDto DIR = new ComponentDto()
75     // no id yet
76     .setScope(Scopes.PROJECT)
77     .setQualifier(Qualifiers.DIRECTORY)
78     .setKey("the_dir")
79     .setName("The Dir")
80     .setDescription("description of dir")
81     .setEnabled(true)
82     .setUuid(DIR_UUID)
83     .setUuidPath(UUID_PATH)
84     .setBranchUuid(PROJECT_UUID);
85
86   private static final String FILE_UUID = "FILE_UUID";
87   private static final ComponentDto FILE = new ComponentDto()
88     // no id yet
89     .setScope(Scopes.FILE)
90     .setQualifier(Qualifiers.FILE)
91     .setKey("the_file")
92     .setName("The File")
93     .setUuid(FILE_UUID)
94     .setUuidPath(UUID_PATH + UUID_PATH_SEPARATOR + FILE_UUID)
95     .setEnabled(true)
96     .setBranchUuid(PROJECT_UUID);
97
98   @Rule
99   public DbTester dbTester = DbTester.create(System2.INSTANCE);
100   @Rule
101   public LogTester logTester = new LogTester();
102
103   private final ComponentRepositoryImpl componentRepository = new ComponentRepositoryImpl();
104   private final FakeDumpWriter dumpWriter = new FakeDumpWriter();
105   private final ProjectHolder projectHolder = mock(ProjectHolder.class);
106   private final ExportAnalysesStep underTest = new ExportAnalysesStep(dbTester.getDbClient(), projectHolder, componentRepository, dumpWriter);
107
108   @Before
109   public void setUp() {
110     logTester.setLevel(Level.DEBUG);
111     ComponentDto projectDto = dbTester.components().insertPublicProject(PROJECT).getMainBranchComponent();
112     componentRepository.register(1, projectDto.uuid(), false);
113     dbTester.getDbClient().componentDao().insert(dbTester.getSession(), Set.of(DIR, FILE), true);
114     dbTester.commit();
115     when(projectHolder.projectDto()).thenReturn(dbTester.components().getProjectDtoByMainBranch(projectDto));
116   }
117
118   @Test
119   public void getDescription_is_defined() {
120     assertThat(underTest.getDescription()).isEqualTo("Export analyses");
121   }
122
123   @Test
124   @UseDataProvider("versionAndBuildStringCombinations")
125   public void export_analyses(@Nullable String version, @Nullable String buildString) {
126     SnapshotDto firstAnalysis = newAnalysis("U_1", 1_450_000_000_000L, PROJECT.uuid(), "1.0", false, "1.0.2.3", 1_450_000_000_000L);
127     SnapshotDto secondAnalysis = newAnalysis("U_4", 1_460_000_000_000L, PROJECT.uuid(), "1.1", true, "1.1.3.4", 1_460_000_000_000L);
128     SnapshotDto thirdAnalysis = newAnalysis("U_7", 1_460_000_000_000L, PROJECT.uuid(), version, true, buildString, 1_470_000_000_000L);
129     dbTester.getDbClient().snapshotDao().insert(dbTester.getSession(), firstAnalysis, secondAnalysis, thirdAnalysis);
130     dbTester.commit();
131
132     underTest.execute(new TestComputationStepContext());
133
134     assertThat(logTester.logs(Level.DEBUG)).contains("3 analyses exported");
135     List<ProjectDump.Analysis> analyses = dumpWriter.getWrittenMessagesOf(DumpElement.ANALYSES);
136     assertThat(analyses).hasSize(3);
137     assertAnalysis(analyses.get(0), PROJECT, firstAnalysis);
138     assertAnalysis(analyses.get(1), PROJECT, secondAnalysis);
139     assertAnalysis(analyses.get(2), PROJECT, thirdAnalysis);
140   }
141
142   @DataProvider
143   public static Object[][] versionAndBuildStringCombinations() {
144     String version = randomAlphabetic(7);
145     String buildString = randomAlphabetic(12);
146     return new Object[][] {
147       {null, null},
148       {version, null},
149       {null, buildString},
150       {version, buildString},
151       {"", ""},
152       {version, ""},
153       {"", buildString},
154     };
155   }
156
157   @Test
158   public void export_analyses_by_ordering_by_technical_creation_date() {
159     SnapshotDto firstAnalysis = newAnalysis("U_1", 1_450_000_000_000L, PROJECT.uuid(), "1.0", false, "1.0.2.3", 3_000_000_000_000L);
160     SnapshotDto secondAnalysis = newAnalysis("U_4", 1_460_000_000_000L, PROJECT.uuid(), "1.1", true, "1.1.3.4", 1_000_000_000_000L);
161     SnapshotDto thirdAnalysis = newAnalysis("U_7", 1_460_500_000_000L, PROJECT.uuid(), null, true, null, 2_000_000_000_000L);
162     dbTester.getDbClient().snapshotDao().insert(dbTester.getSession(), firstAnalysis, secondAnalysis, thirdAnalysis);
163     dbTester.commit();
164
165     underTest.execute(new TestComputationStepContext());
166
167     List<ProjectDump.Analysis> analyses = dumpWriter.getWrittenMessagesOf(DumpElement.ANALYSES);
168     assertAnalysis(analyses.get(0), PROJECT, secondAnalysis);
169     assertAnalysis(analyses.get(1), PROJECT, thirdAnalysis);
170     assertAnalysis(analyses.get(2), PROJECT, firstAnalysis);
171   }
172
173   @Test
174   public void export_provisioned_projects_without_any_analyses() {
175     underTest.execute(new TestComputationStepContext());
176
177     List<ProjectDump.Analysis> analyses = dumpWriter.getWrittenMessagesOf(DumpElement.ANALYSES);
178     assertThat(analyses).isEmpty();
179     assertThat(logTester.logs(Level.DEBUG)).contains("0 analyses exported");
180   }
181
182   @Test
183   public void throws_ISE_if_error() {
184     SnapshotDto firstAnalysis = newAnalysis("U_1", 1_450_000_000_000L, PROJECT.uuid(), "1.0", false, "1.0.2.3", 1);
185     SnapshotDto secondAnalysis = newAnalysis("U_4", 1_460_000_000_000L, PROJECT.uuid(), "1.1", true, "1.1.3.4", 2);
186     dbTester.getDbClient().snapshotDao().insert(dbTester.getSession(), firstAnalysis, secondAnalysis);
187     dbTester.commit();
188     dumpWriter.failIfMoreThan(1, DumpElement.ANALYSES);
189
190     assertThatThrownBy(() -> underTest.execute(new TestComputationStepContext()))
191       .isInstanceOf(IllegalStateException.class)
192       .hasMessage("Analysis Export failed after processing 1 analyses successfully");
193   }
194
195   private static SnapshotDto newAnalysis(String uuid, long date, String componentUuid, @Nullable String version, boolean isLast, @Nullable String buildString, long analysisDate) {
196     return new SnapshotDto()
197       .setUuid(uuid)
198       .setCreatedAt(date)
199       .setRootComponentUuid(componentUuid)
200       .setProjectVersion(version)
201       .setBuildString(buildString)
202       .setLast(isLast)
203       .setStatus(SnapshotDto.STATUS_PROCESSED)
204       .setAnalysisDate(analysisDate);
205   }
206
207   private static void assertAnalysis(ProjectDump.Analysis analysis, ComponentDto component, SnapshotDto dto) {
208     assertThat(analysis.getUuid()).isEqualTo(dto.getUuid());
209     assertThat(analysis.getComponentRef()).isOne();
210     assertThat(analysis.getDate()).isEqualTo(dto.getCreatedAt());
211     assertThat(analysis.getProjectVersion()).isEqualTo(defaultString(dto.getProjectVersion()));
212     assertThat(analysis.getBuildString()).isEqualTo(defaultString(dto.getBuildString()));
213   }
214 }