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.

MetadataPublisherTest.java 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2023 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.scanner.report;
  21. import com.google.common.collect.ImmutableMap;
  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.io.IOException;
  26. import java.nio.file.Files;
  27. import java.nio.file.Path;
  28. import java.nio.file.Paths;
  29. import java.util.Collections;
  30. import java.util.Date;
  31. import java.util.Optional;
  32. import javax.annotation.Nullable;
  33. import org.junit.Before;
  34. import org.junit.Rule;
  35. import org.junit.Test;
  36. import org.junit.rules.TemporaryFolder;
  37. import org.junit.runner.RunWith;
  38. import org.sonar.api.batch.bootstrap.ProjectDefinition;
  39. import org.sonar.api.batch.fs.internal.DefaultInputModule;
  40. import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
  41. import org.sonar.api.batch.scm.ScmProvider;
  42. import org.sonar.core.plugin.PluginType;
  43. import org.sonar.scanner.ProjectInfo;
  44. import org.sonar.scanner.bootstrap.ScannerPlugin;
  45. import org.sonar.scanner.bootstrap.ScannerPluginRepository;
  46. import org.sonar.scanner.cpd.CpdSettings;
  47. import org.sonar.scanner.fs.InputModuleHierarchy;
  48. import org.sonar.scanner.protocol.output.FileStructure;
  49. import org.sonar.scanner.protocol.output.ScannerReport;
  50. import org.sonar.scanner.protocol.output.ScannerReportReader;
  51. import org.sonar.scanner.protocol.output.ScannerReportWriter;
  52. import org.sonar.scanner.repository.ReferenceBranchSupplier;
  53. import org.sonar.scanner.rule.QProfile;
  54. import org.sonar.scanner.rule.QualityProfiles;
  55. import org.sonar.scanner.scan.branch.BranchConfiguration;
  56. import org.sonar.scanner.scan.branch.BranchType;
  57. import org.sonar.scanner.scan.filesystem.InputComponentStore;
  58. import org.sonar.scanner.scm.ScmConfiguration;
  59. import org.sonar.scanner.scm.ScmRevision;
  60. import static java.util.Collections.emptyMap;
  61. import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
  62. import static org.assertj.core.api.Assertions.assertThat;
  63. import static org.assertj.core.api.Assertions.entry;
  64. import static org.mockito.ArgumentMatchers.any;
  65. import static org.mockito.Mockito.mock;
  66. import static org.mockito.Mockito.when;
  67. @RunWith(DataProviderRunner.class)
  68. public class MetadataPublisherTest {
  69. @Rule
  70. public TemporaryFolder temp = new TemporaryFolder();
  71. private MetadataPublisher underTest;
  72. private final QualityProfiles qProfiles = mock(QualityProfiles.class);
  73. private final ProjectInfo projectInfo = mock(ProjectInfo.class);
  74. private final CpdSettings cpdSettings = mock(CpdSettings.class);
  75. private final ReferenceBranchSupplier referenceBranchSupplier = mock(ReferenceBranchSupplier.class);
  76. private final ScannerPluginRepository pluginRepository = mock(ScannerPluginRepository.class);
  77. private BranchConfiguration branches;
  78. private ScmConfiguration scmConfiguration;
  79. private final ScmProvider scmProvider = mock(ScmProvider.class);
  80. private final ScmRevision scmRevision = mock(ScmRevision.class);
  81. private final InputComponentStore componentStore = mock(InputComponentStore.class);
  82. private ScannerReportWriter writer;
  83. private ScannerReportReader reader;
  84. @Before
  85. public void prepare() throws IOException {
  86. FileStructure fileStructure = new FileStructure(temp.newFolder());
  87. writer = new ScannerReportWriter(fileStructure);
  88. reader = new ScannerReportReader(fileStructure);
  89. when(projectInfo.getAnalysisDate()).thenReturn(new Date(1234567L));
  90. when(scmProvider.relativePathFromScmRoot(any(Path.class))).thenReturn(Paths.get("dummy/path"));
  91. when(scmProvider.revisionId(any(Path.class))).thenReturn("dummy-sha1");
  92. createPublisher(ProjectDefinition.create());
  93. when(pluginRepository.getPluginsByKey()).thenReturn(emptyMap());
  94. }
  95. private void createPublisher(ProjectDefinition def) throws IOException {
  96. Path rootBaseDir = temp.newFolder().toPath();
  97. Path moduleBaseDir = rootBaseDir.resolve("moduleDir");
  98. Files.createDirectory(moduleBaseDir);
  99. DefaultInputModule rootModule = new DefaultInputModule(def
  100. .setBaseDir(rootBaseDir.toFile())
  101. .setKey("root")
  102. .setWorkDir(temp.newFolder()), TestInputFileBuilder.nextBatchId());
  103. InputModuleHierarchy inputModuleHierarchy = mock(InputModuleHierarchy.class);
  104. when(inputModuleHierarchy.root()).thenReturn(rootModule);
  105. DefaultInputModule child = new DefaultInputModule(ProjectDefinition.create()
  106. .setKey("module")
  107. .setBaseDir(moduleBaseDir.toFile())
  108. .setWorkDir(temp.newFolder()), TestInputFileBuilder.nextBatchId());
  109. when(inputModuleHierarchy.children(rootModule)).thenReturn(Collections.singletonList(child));
  110. when(inputModuleHierarchy.relativePathToRoot(child)).thenReturn("modulePath");
  111. when(inputModuleHierarchy.relativePathToRoot(rootModule)).thenReturn("");
  112. branches = mock(BranchConfiguration.class);
  113. scmConfiguration = mock(ScmConfiguration.class);
  114. when(scmConfiguration.provider()).thenReturn(scmProvider);
  115. underTest = new MetadataPublisher(projectInfo, inputModuleHierarchy, qProfiles, cpdSettings,
  116. pluginRepository, branches, scmRevision, componentStore, scmConfiguration, referenceBranchSupplier);
  117. }
  118. @Test
  119. public void write_metadata() {
  120. Date date = new Date();
  121. when(qProfiles.findAll()).thenReturn(Collections.singletonList(new QProfile("q1", "Q1", "java", date)));
  122. when(pluginRepository.getPluginsByKey()).thenReturn(ImmutableMap.of(
  123. "java", new ScannerPlugin("java", 12345L, PluginType.BUNDLED, null),
  124. "php", new ScannerPlugin("php", 45678L, PluginType.BUNDLED, null)));
  125. when(referenceBranchSupplier.getFromProperties()).thenReturn("newCodeReference");
  126. underTest.publish(writer);
  127. ScannerReport.Metadata metadata = reader.readMetadata();
  128. assertThat(metadata.getAnalysisDate()).isEqualTo(1234567L);
  129. assertThat(metadata.getNewCodeReferenceBranch()).isEqualTo("newCodeReference");
  130. assertThat(metadata.getProjectKey()).isEqualTo("root");
  131. assertThat(metadata.getProjectVersion()).isEmpty();
  132. assertThat(metadata.getNotAnalyzedFilesByLanguageCount()).isZero();
  133. assertThat(metadata.getQprofilesPerLanguageMap()).containsOnly(entry("java", org.sonar.scanner.protocol.output.ScannerReport.Metadata.QProfile.newBuilder()
  134. .setKey("q1")
  135. .setName("Q1")
  136. .setLanguage("java")
  137. .setRulesUpdatedAt(date.getTime())
  138. .build()));
  139. assertThat(metadata.getPluginsByKey()).containsOnly(entry("java", org.sonar.scanner.protocol.output.ScannerReport.Metadata.Plugin.newBuilder()
  140. .setKey("java")
  141. .setUpdatedAt(12345)
  142. .build()),
  143. entry("php", org.sonar.scanner.protocol.output.ScannerReport.Metadata.Plugin.newBuilder()
  144. .setKey("php")
  145. .setUpdatedAt(45678)
  146. .build()));
  147. }
  148. @Test
  149. public void write_not_analysed_file_counts() {
  150. when(componentStore.getNotAnalysedFilesByLanguage()).thenReturn(ImmutableMap.of("c", 10, "cpp", 20));
  151. underTest.publish(writer);
  152. ScannerReport.Metadata metadata = reader.readMetadata();
  153. assertThat(metadata.getNotAnalyzedFilesByLanguageMap()).contains(entry("c", 10), entry("cpp", 20));
  154. }
  155. @Test
  156. @UseDataProvider("projectVersions")
  157. public void write_project_version(@Nullable String projectVersion, String expected) {
  158. when(projectInfo.getProjectVersion()).thenReturn(Optional.ofNullable(projectVersion));
  159. underTest.publish(writer);
  160. ScannerReport.Metadata metadata = reader.readMetadata();
  161. assertThat(metadata.getProjectVersion()).isEqualTo(expected);
  162. }
  163. @DataProvider
  164. public static Object[][] projectVersions() {
  165. String version = randomAlphabetic(15);
  166. return new Object[][] {
  167. {null, ""},
  168. {"", ""},
  169. {"5.6.3", "5.6.3"},
  170. {version, version}
  171. };
  172. }
  173. @Test
  174. @UseDataProvider("buildStrings")
  175. public void write_buildString(@Nullable String buildString, String expected) {
  176. when(projectInfo.getBuildString()).thenReturn(Optional.ofNullable(buildString));
  177. underTest.publish(writer);
  178. ScannerReport.Metadata metadata = reader.readMetadata();
  179. assertThat(metadata.getBuildString()).isEqualTo(expected);
  180. }
  181. @DataProvider
  182. public static Object[][] buildStrings() {
  183. String randomBuildString = randomAlphabetic(15);
  184. return new Object[][] {
  185. {null, ""},
  186. {"", ""},
  187. {"5.6.3", "5.6.3"},
  188. {randomBuildString, randomBuildString}
  189. };
  190. }
  191. @Test
  192. public void write_branch_info() {
  193. String branchName = "name";
  194. String targetName = "target";
  195. when(branches.branchName()).thenReturn(branchName);
  196. when(branches.branchType()).thenReturn(BranchType.BRANCH);
  197. when(branches.targetBranchName()).thenReturn(targetName);
  198. underTest.publish(writer);
  199. ScannerReport.Metadata metadata = reader.readMetadata();
  200. assertThat(metadata.getBranchName()).isEqualTo(branchName);
  201. assertThat(metadata.getBranchType()).isEqualTo(ScannerReport.Metadata.BranchType.BRANCH);
  202. assertThat(metadata.getReferenceBranchName()).isEmpty();
  203. assertThat(metadata.getTargetBranchName()).isEqualTo(targetName);
  204. }
  205. @Test
  206. public void dont_write_new_code_reference_if_not_specified_in_properties() {
  207. when(referenceBranchSupplier.get()).thenReturn("ref");
  208. when(referenceBranchSupplier.getFromProperties()).thenReturn(null);
  209. underTest.publish(writer);
  210. ScannerReport.Metadata metadata = reader.readMetadata();
  211. assertThat(metadata.getNewCodeReferenceBranch()).isEmpty();
  212. }
  213. @Test
  214. public void write_project_basedir() {
  215. String path = "some/dir";
  216. Path relativePathFromScmRoot = Paths.get(path);
  217. when(scmProvider.relativePathFromScmRoot(any(Path.class))).thenReturn(relativePathFromScmRoot);
  218. underTest.publish(writer);
  219. ScannerReport.Metadata metadata = reader.readMetadata();
  220. assertThat(metadata.getRelativePathFromScmRoot()).isEqualTo(path);
  221. }
  222. @Test
  223. public void write_revision_id() throws Exception {
  224. String revisionId = "some-sha1";
  225. when(scmRevision.get()).thenReturn(Optional.of(revisionId));
  226. underTest.publish(writer);
  227. ScannerReport.Metadata metadata = reader.readMetadata();
  228. assertThat(metadata.getScmRevisionId()).isEqualTo(revisionId);
  229. }
  230. @Test
  231. public void should_not_crash_when_scm_provider_does_not_support_relativePathFromScmRoot() {
  232. ScmProvider fakeScmProvider = new ScmProvider() {
  233. @Override
  234. public String key() {
  235. return "foo";
  236. }
  237. };
  238. when(scmConfiguration.provider()).thenReturn(fakeScmProvider);
  239. underTest.publish(writer);
  240. ScannerReport.Metadata metadata = reader.readMetadata();
  241. assertThat(metadata.getRelativePathFromScmRoot()).isEmpty();
  242. }
  243. }