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.

PluginInfoTest.java 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  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.core.platform;
  21. import com.tngtech.java.junit.dataprovider.DataProvider;
  22. import com.tngtech.java.junit.dataprovider.DataProviderRunner;
  23. import com.tngtech.java.junit.dataprovider.UseDataProvider;
  24. import java.io.File;
  25. import java.io.IOException;
  26. import java.util.Arrays;
  27. import java.util.List;
  28. import javax.annotation.Nullable;
  29. import org.apache.commons.io.FileUtils;
  30. import org.assertj.core.api.Assertions;
  31. import org.junit.Rule;
  32. import org.junit.Test;
  33. import org.junit.rules.ExpectedException;
  34. import org.junit.rules.TemporaryFolder;
  35. import org.junit.runner.RunWith;
  36. import org.sonar.api.utils.MessageException;
  37. import org.sonar.api.utils.ZipUtils;
  38. import org.sonar.updatecenter.common.PluginManifest;
  39. import org.sonar.updatecenter.common.Version;
  40. import static com.google.common.collect.Ordering.natural;
  41. import static org.assertj.core.api.Assertions.assertThat;
  42. import static org.junit.Assert.fail;
  43. @RunWith(DataProviderRunner.class)
  44. public class PluginInfoTest {
  45. @Rule
  46. public TemporaryFolder temp = new TemporaryFolder();
  47. @Rule
  48. public ExpectedException expectedException = ExpectedException.none();
  49. @Test
  50. public void test_RequiredPlugin() {
  51. PluginInfo.RequiredPlugin plugin = PluginInfo.RequiredPlugin.parse("java:1.1");
  52. assertThat(plugin.getKey()).isEqualTo("java");
  53. assertThat(plugin.getMinimalVersion().getName()).isEqualTo("1.1");
  54. assertThat(plugin.toString()).isEqualTo("java:1.1");
  55. assertThat(plugin.equals(PluginInfo.RequiredPlugin.parse("java:1.2"))).isTrue();
  56. assertThat(plugin.equals(PluginInfo.RequiredPlugin.parse("php:1.2"))).isFalse();
  57. try {
  58. PluginInfo.RequiredPlugin.parse("java");
  59. fail();
  60. } catch (IllegalArgumentException expected) {
  61. // ok
  62. }
  63. }
  64. @Test
  65. public void test_comparison() {
  66. PluginInfo java1 = new PluginInfo("java").setVersion(Version.create("1.0"));
  67. PluginInfo java2 = new PluginInfo("java").setVersion(Version.create("2.0"));
  68. PluginInfo javaNoVersion = new PluginInfo("java");
  69. PluginInfo cobol = new PluginInfo("cobol").setVersion(Version.create("1.0"));
  70. PluginInfo noVersion = new PluginInfo("noVersion");
  71. List<PluginInfo> plugins = Arrays.asList(java1, cobol, javaNoVersion, noVersion, java2);
  72. List<PluginInfo> ordered = natural().sortedCopy(plugins);
  73. Assertions.assertThat(ordered.get(0)).isSameAs(cobol);
  74. Assertions.assertThat(ordered.get(1)).isSameAs(javaNoVersion);
  75. Assertions.assertThat(ordered.get(2)).isSameAs(java1);
  76. Assertions.assertThat(ordered.get(3)).isSameAs(java2);
  77. Assertions.assertThat(ordered.get(4)).isSameAs(noVersion);
  78. }
  79. @Test
  80. public void test_equals() {
  81. PluginInfo java1 = new PluginInfo("java").setVersion(Version.create("1.0"));
  82. PluginInfo java2 = new PluginInfo("java").setVersion(Version.create("2.0"));
  83. PluginInfo javaNoVersion = new PluginInfo("java");
  84. PluginInfo cobol = new PluginInfo("cobol").setVersion(Version.create("1.0"));
  85. assertThat(java1.equals(java1)).isTrue();
  86. assertThat(java1.equals(java2)).isFalse();
  87. assertThat(java1.equals(javaNoVersion)).isFalse();
  88. assertThat(java1.equals(cobol)).isFalse();
  89. assertThat(java1.equals("java:1.0")).isFalse();
  90. assertThat(java1.equals(null)).isFalse();
  91. assertThat(javaNoVersion.equals(javaNoVersion)).isTrue();
  92. assertThat(java1.hashCode()).isEqualTo(java1.hashCode());
  93. assertThat(javaNoVersion.hashCode()).isEqualTo(javaNoVersion.hashCode());
  94. }
  95. /**
  96. * SNAPSHOT versions of SonarQube are built on local developer machines only.
  97. * All other build environments have unique release versions (6.3.0.12345).
  98. */
  99. @Test
  100. public void test_compatibility_with_snapshot_version_of_sonarqube() {
  101. // plugins compatible with 5.6 LTS
  102. assertThat(withMinSqVersion("5.6").isCompatibleWith("6.3-SNAPSHOT")).isTrue();
  103. assertThat(withMinSqVersion("5.6.1").isCompatibleWith("6.3-SNAPSHOT")).isTrue();
  104. // plugin build with old release candidates of SonarQube (RC technical versions have been removed
  105. // in SonarQube 6.3)
  106. assertThat(withMinSqVersion("5.6-RC1").isCompatibleWith("6.3-SNAPSHOT")).isTrue();
  107. assertThat(withMinSqVersion("6.2-RC1").isCompatibleWith("6.3-SNAPSHOT")).isTrue();
  108. // plugin built with snapshot version of SonarQube
  109. assertThat(withMinSqVersion("5.6-SNAPSHOT").isCompatibleWith("6.3-SNAPSHOT")).isTrue();
  110. assertThat(withMinSqVersion("6.3-SNAPSHOT").isCompatibleWith("6.3-SNAPSHOT")).isTrue();
  111. assertThat(withMinSqVersion("6.4-SNAPSHOT").isCompatibleWith("6.3-SNAPSHOT")).isFalse();
  112. // plugin built with SonarQube releases
  113. assertThat(withMinSqVersion("6.3.0.5000").isCompatibleWith("6.3-SNAPSHOT")).isTrue();
  114. assertThat(withMinSqVersion("6.3.1.5000").isCompatibleWith("6.3-SNAPSHOT")).isTrue();
  115. assertThat(withMinSqVersion("6.3.1.5000").isCompatibleWith("6.4-SNAPSHOT")).isTrue();
  116. assertThat(withMinSqVersion("6.4.0.5000").isCompatibleWith("6.3-SNAPSHOT")).isFalse();
  117. // no constraint
  118. assertThat(withMinSqVersion(null).isCompatibleWith("6.3-SNAPSHOT")).isTrue();
  119. }
  120. /**
  121. * @see #test_compatibility_with_snapshot_version_of_sonarqube
  122. */
  123. @Test
  124. public void test_compatibility_with_release_version_of_sonarqube() {
  125. // plugins compatible with 5.6 LTS
  126. assertThat(withMinSqVersion("5.6").isCompatibleWith("6.3.0.5000")).isTrue();
  127. assertThat(withMinSqVersion("5.6.1").isCompatibleWith("6.3.0.5000")).isTrue();
  128. // plugin build with old release candidates of SonarQube (RC technical versions have been removed
  129. // in SonarQube 6.3)
  130. assertThat(withMinSqVersion("5.6-RC1").isCompatibleWith("6.3.0.5000")).isTrue();
  131. assertThat(withMinSqVersion("6.2-RC1").isCompatibleWith("6.3.0.5000")).isTrue();
  132. // plugin built with snapshot version of SonarQube
  133. assertThat(withMinSqVersion("5.6-SNAPSHOT").isCompatibleWith("6.3.0.5000")).isTrue();
  134. assertThat(withMinSqVersion("6.3-SNAPSHOT").isCompatibleWith("6.3.0.5000")).isTrue();
  135. assertThat(withMinSqVersion("6.3-SNAPSHOT").isCompatibleWith("6.3.1.6000")).isTrue();
  136. assertThat(withMinSqVersion("6.4-SNAPSHOT").isCompatibleWith("6.3.0.5000")).isFalse();
  137. // plugin built with SonarQube releases
  138. assertThat(withMinSqVersion("6.3.0.5000").isCompatibleWith("6.3.0.4000")).isFalse();
  139. assertThat(withMinSqVersion("6.3.0.5000").isCompatibleWith("6.3.0.5000")).isTrue();
  140. assertThat(withMinSqVersion("6.3.0.5000").isCompatibleWith("6.3.1.6000")).isTrue();
  141. assertThat(withMinSqVersion("6.4.0.7000").isCompatibleWith("6.3.0.5000")).isFalse();
  142. // no constraint
  143. assertThat(withMinSqVersion(null).isCompatibleWith("6.3.0.5000")).isTrue();
  144. }
  145. @Test
  146. public void create_from_minimal_manifest() throws Exception {
  147. PluginManifest manifest = new PluginManifest();
  148. manifest.setKey("java");
  149. manifest.setVersion("1.0");
  150. manifest.setName("Java");
  151. manifest.setMainClass("org.foo.FooPlugin");
  152. File jarFile = temp.newFile();
  153. PluginInfo pluginInfo = PluginInfo.create(jarFile, manifest);
  154. assertThat(pluginInfo.getKey()).isEqualTo("java");
  155. assertThat(pluginInfo.getName()).isEqualTo("Java");
  156. assertThat(pluginInfo.getVersion().getName()).isEqualTo("1.0");
  157. assertThat(pluginInfo.getJarFile()).isSameAs(jarFile);
  158. assertThat(pluginInfo.getMainClass()).isEqualTo("org.foo.FooPlugin");
  159. assertThat(pluginInfo.getBasePlugin()).isNull();
  160. assertThat(pluginInfo.getDescription()).isNull();
  161. assertThat(pluginInfo.getHomepageUrl()).isNull();
  162. assertThat(pluginInfo.getImplementationBuild()).isNull();
  163. assertThat(pluginInfo.getIssueTrackerUrl()).isNull();
  164. assertThat(pluginInfo.getLicense()).isNull();
  165. assertThat(pluginInfo.getOrganizationName()).isNull();
  166. assertThat(pluginInfo.getOrganizationUrl()).isNull();
  167. assertThat(pluginInfo.getMinimalSqVersion()).isNull();
  168. assertThat(pluginInfo.getRequiredPlugins()).isEmpty();
  169. assertThat(pluginInfo.isSonarLintSupported()).isFalse();
  170. }
  171. @Test
  172. public void create_from_complete_manifest() throws Exception {
  173. PluginManifest manifest = new PluginManifest();
  174. manifest.setKey("fbcontrib");
  175. manifest.setVersion("2.0");
  176. manifest.setName("Java");
  177. manifest.setMainClass("org.fb.FindbugsPlugin");
  178. manifest.setBasePlugin("findbugs");
  179. manifest.setSonarVersion("4.5.1");
  180. manifest.setDescription("the desc");
  181. manifest.setHomepage("http://fbcontrib.org");
  182. manifest.setImplementationBuild("SHA1");
  183. manifest.setLicense("LGPL");
  184. manifest.setOrganization("SonarSource");
  185. manifest.setOrganizationUrl("http://sonarsource.com");
  186. manifest.setIssueTrackerUrl("http://jira.com");
  187. manifest.setRequirePlugins(new String[]{"java:2.0", "pmd:1.3"});
  188. manifest.setSonarLintSupported(true);
  189. File jarFile = temp.newFile();
  190. PluginInfo pluginInfo = PluginInfo.create(jarFile, manifest);
  191. assertThat(pluginInfo.getBasePlugin()).isEqualTo("findbugs");
  192. assertThat(pluginInfo.getDescription()).isEqualTo("the desc");
  193. assertThat(pluginInfo.getHomepageUrl()).isEqualTo("http://fbcontrib.org");
  194. assertThat(pluginInfo.getImplementationBuild()).isEqualTo("SHA1");
  195. assertThat(pluginInfo.getIssueTrackerUrl()).isEqualTo("http://jira.com");
  196. assertThat(pluginInfo.getLicense()).isEqualTo("LGPL");
  197. assertThat(pluginInfo.getOrganizationName()).isEqualTo("SonarSource");
  198. assertThat(pluginInfo.getOrganizationUrl()).isEqualTo("http://sonarsource.com");
  199. assertThat(pluginInfo.getMinimalSqVersion().getName()).isEqualTo("4.5.1");
  200. assertThat(pluginInfo.getRequiredPlugins()).extracting("key").containsOnly("java", "pmd");
  201. assertThat(pluginInfo.isSonarLintSupported()).isTrue();
  202. }
  203. @Test
  204. @UseDataProvider("licenseVersions")
  205. public void requiredPlugin_license_is_ignored_when_reading_manifest(String version) throws IOException {
  206. PluginManifest manifest = new PluginManifest();
  207. manifest.setKey("java");
  208. manifest.setVersion("1.0");
  209. manifest.setName("Java");
  210. manifest.setMainClass("org.foo.FooPlugin");
  211. manifest.setRequirePlugins(new String[]{"license:" + version});
  212. File jarFile = temp.newFile();
  213. PluginInfo pluginInfo = PluginInfo.create(jarFile, manifest);
  214. assertThat(pluginInfo.getRequiredPlugins()).isEmpty();
  215. }
  216. @Test
  217. @UseDataProvider("licenseVersions")
  218. public void requiredPlugin_license_among_others_is_ignored_when_reading_manifest(String version) throws IOException {
  219. PluginManifest manifest = new PluginManifest();
  220. manifest.setKey("java");
  221. manifest.setVersion("1.0");
  222. manifest.setName("Java");
  223. manifest.setMainClass("org.foo.FooPlugin");
  224. manifest.setRequirePlugins(new String[]{"java:2.0", "license:" + version, "pmd:1.3"});
  225. File jarFile = temp.newFile();
  226. PluginInfo pluginInfo = PluginInfo.create(jarFile, manifest);
  227. assertThat(pluginInfo.getRequiredPlugins()).extracting("key").containsOnly("java", "pmd");
  228. }
  229. @DataProvider
  230. public static Object[][] licenseVersions() {
  231. return new Object[][]{
  232. {"0.3"},
  233. {"7.2.0.1253"}
  234. };
  235. }
  236. @Test
  237. public void create_from_file() {
  238. File checkstyleJar = FileUtils.toFile(getClass().getResource("/org/sonar/core/platform/sonar-checkstyle-plugin-2.8.jar"));
  239. PluginInfo checkstyleInfo = PluginInfo.create(checkstyleJar);
  240. assertThat(checkstyleInfo.getName()).isEqualTo("Checkstyle");
  241. assertThat(checkstyleInfo.getDocumentationPath()).isNull();
  242. assertThat(checkstyleInfo.getMinimalSqVersion()).isEqualTo(Version.create("2.8"));
  243. }
  244. @Test
  245. public void create_from_file_with_documentation() {
  246. File jarWithDocs = FileUtils.toFile(getClass().getResource("/org/sonar/core/platform/jar_with_documentation.jar"));
  247. PluginInfo checkstyleInfo = PluginInfo.create(jarWithDocs);
  248. assertThat(checkstyleInfo.getDocumentationPath()).isNotBlank();
  249. assertThat(checkstyleInfo.getDocumentationPath()).isEqualTo("static/documentation.md");
  250. }
  251. @Test
  252. public void test_toString() {
  253. PluginInfo pluginInfo = new PluginInfo("java").setVersion(Version.create("1.1"));
  254. assertThat(pluginInfo.toString()).isEqualTo("[java / 1.1]");
  255. pluginInfo.setImplementationBuild("SHA1");
  256. assertThat(pluginInfo.toString()).isEqualTo("[java / 1.1 / SHA1]");
  257. }
  258. /**
  259. * The English bundle plugin was removed in 5.2. L10n plugins do not need to declare
  260. * it as base plugin anymore
  261. */
  262. @Test
  263. public void l10n_plugins_should_not_extend_english_plugin() {
  264. PluginInfo pluginInfo = new PluginInfo("l10nfr").setBasePlugin("l10nen");
  265. assertThat(pluginInfo.getBasePlugin()).isNull();
  266. }
  267. @Test
  268. public void fail_when_jar_is_not_a_plugin() throws IOException {
  269. // this JAR has a manifest but is not a plugin
  270. File jarRootDir = temp.newFolder();
  271. FileUtils.write(new File(jarRootDir, "META-INF/MANIFEST.MF"), "Build-Jdk: 1.6.0_15");
  272. File jar = temp.newFile();
  273. ZipUtils.zipDir(jarRootDir, jar);
  274. expectedException.expect(MessageException.class);
  275. expectedException.expectMessage("File is not a plugin. Please delete it and restart: " + jar.getAbsolutePath());
  276. PluginInfo.create(jar);
  277. }
  278. PluginInfo withMinSqVersion(@Nullable String version) {
  279. PluginInfo pluginInfo = new PluginInfo("foo");
  280. if (version != null) {
  281. pluginInfo.setMinimalSqVersion(Version.create(version));
  282. }
  283. return pluginInfo;
  284. }
  285. }