You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ExportAnalysesStepTest.java 9.5KB

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