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 12KB

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