PageRenderTime 24ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/atlassian-plugins-core/src/test/java/com/atlassian/plugin/loaders/TestDirectoryPluginLoader.java

https://bitbucket.org/purewind/atlassian-plugins
Java | 306 lines | 245 code | 55 blank | 6 comment | 10 complexity | 21d63f9476b90c0332d270719549e4de MD5 | raw file
  1. package com.atlassian.plugin.loaders;
  2. import com.atlassian.plugin.DefaultModuleDescriptorFactory;
  3. import com.atlassian.plugin.Plugin;
  4. import com.atlassian.plugin.PluginAccessor;
  5. import com.atlassian.plugin.PluginException;
  6. import com.atlassian.plugin.PluginParseException;
  7. import com.atlassian.plugin.event.PluginEventManager;
  8. import com.atlassian.plugin.event.impl.DefaultPluginEventManager;
  9. import com.atlassian.plugin.factories.LegacyDynamicPluginFactory;
  10. import com.atlassian.plugin.factories.PluginFactory;
  11. import com.atlassian.plugin.hostcontainer.DefaultHostContainer;
  12. import com.atlassian.plugin.impl.UnloadablePlugin;
  13. import com.atlassian.plugin.loaders.classloading.DirectoryPluginLoaderUtils;
  14. import com.atlassian.plugin.mock.MockAnimalModuleDescriptor;
  15. import com.atlassian.plugin.mock.MockBear;
  16. import com.atlassian.plugin.mock.MockMineralModuleDescriptor;
  17. import com.atlassian.plugin.test.PluginJarBuilder;
  18. import com.google.common.base.Predicate;
  19. import com.google.common.collect.ImmutableList;
  20. import com.google.common.collect.Iterables;
  21. import org.apache.commons.io.FileUtils;
  22. import org.junit.After;
  23. import org.junit.Before;
  24. import org.junit.Test;
  25. import java.io.File;
  26. import java.io.FileOutputStream;
  27. import java.io.FilenameFilter;
  28. import java.io.IOException;
  29. import java.io.OutputStream;
  30. import java.net.URISyntaxException;
  31. import java.util.Iterator;
  32. import java.util.List;
  33. import java.util.jar.JarEntry;
  34. import java.util.jar.JarOutputStream;
  35. import static com.atlassian.plugin.loaders.classloading.DirectoryPluginLoaderUtils.PADDINGTON_JAR;
  36. import static org.junit.Assert.assertEquals;
  37. import static org.junit.Assert.assertFalse;
  38. import static org.junit.Assert.assertNotNull;
  39. import static org.junit.Assert.assertNull;
  40. import static org.junit.Assert.assertTrue;
  41. import static org.junit.Assert.fail;
  42. public class TestDirectoryPluginLoader {
  43. private static final List<PluginFactory> DEFAULT_PLUGIN_FACTORIES = ImmutableList.<PluginFactory>of(
  44. new LegacyDynamicPluginFactory(PluginAccessor.Descriptor.FILENAME));
  45. private PluginEventManager pluginEventManager;
  46. private DirectoryPluginLoader loader;
  47. private DefaultModuleDescriptorFactory moduleDescriptorFactory;
  48. private File pluginsDirectory;
  49. private File pluginsTestDir;
  50. public void createFillAndCleanTempPluginDirectory() throws IOException {
  51. final DirectoryPluginLoaderUtils.ScannerDirectories directories = DirectoryPluginLoaderUtils.createFillAndCleanTempPluginDirectory();
  52. pluginsDirectory = directories.pluginsDirectory;
  53. pluginsTestDir = directories.pluginsTestDir;
  54. }
  55. @Before
  56. public void setUp() throws Exception {
  57. moduleDescriptorFactory = new DefaultModuleDescriptorFactory(new DefaultHostContainer());
  58. pluginEventManager = new DefaultPluginEventManager();
  59. createFillAndCleanTempPluginDirectory();
  60. }
  61. @After
  62. public void tearDown() throws Exception {
  63. FileUtils.deleteDirectory(pluginsTestDir);
  64. }
  65. @Test
  66. public void testAtlassianPlugin() throws Exception {
  67. addTestModuleDecriptors();
  68. loader = new DirectoryPluginLoader(pluginsTestDir, DEFAULT_PLUGIN_FACTORIES, pluginEventManager);
  69. final Iterable<Plugin> plugins = loader.loadAllPlugins(moduleDescriptorFactory);
  70. assertEquals(2, Iterables.size(plugins));
  71. for (final Plugin plugin : plugins) {
  72. assertTrue(plugin.getName().equals("Test Class Loaded Plugin") || plugin.getName().equals("Test Class Loaded Plugin 2"));
  73. if (plugin.getName().equals("Test Class Loaded Plugin")) // asserts for first plugin
  74. {
  75. assertEquals("Test Class Loaded Plugin", plugin.getName());
  76. assertEquals("test.atlassian.plugin.classloaded", plugin.getKey());
  77. assertEquals(1, plugin.getModuleDescriptors().size());
  78. final MockAnimalModuleDescriptor paddingtonDescriptor = (MockAnimalModuleDescriptor) plugin.getModuleDescriptor("paddington");
  79. paddingtonDescriptor.enabled();
  80. assertEquals("Paddington Bear", paddingtonDescriptor.getName());
  81. final MockBear paddington = (MockBear) paddingtonDescriptor.getModule();
  82. assertEquals("com.atlassian.plugin.mock.MockPaddington", paddington.getClass().getName());
  83. } else if (plugin.getName().equals("Test Class Loaded Plugin 2")) // asserts for second plugin
  84. {
  85. assertEquals("Test Class Loaded Plugin 2", plugin.getName());
  86. assertEquals("test.atlassian.plugin.classloaded2", plugin.getKey());
  87. assertEquals(1, plugin.getModuleDescriptors().size());
  88. final MockAnimalModuleDescriptor poohDescriptor = (MockAnimalModuleDescriptor) plugin.getModuleDescriptor("pooh");
  89. poohDescriptor.enabled();
  90. assertEquals("Pooh Bear", poohDescriptor.getName());
  91. final MockBear pooh = (MockBear) poohDescriptor.getModule();
  92. assertEquals("com.atlassian.plugin.mock.MockPooh", pooh.getClass().getName());
  93. } else {
  94. fail("What plugin name?!");
  95. }
  96. }
  97. }
  98. private void addTestModuleDecriptors() {
  99. moduleDescriptorFactory.addModuleDescriptor("animal", MockAnimalModuleDescriptor.class);
  100. moduleDescriptorFactory.addModuleDescriptor("mineral", MockMineralModuleDescriptor.class);
  101. }
  102. @Test
  103. public void testSupportsAdditionAndRemoval() {
  104. loader = new DirectoryPluginLoader(pluginsTestDir, DEFAULT_PLUGIN_FACTORIES, pluginEventManager);
  105. assertTrue(loader.supportsAddition());
  106. assertTrue(loader.supportsRemoval());
  107. }
  108. @Test
  109. public void testNoFoundPlugins() throws PluginParseException {
  110. addTestModuleDecriptors();
  111. loader = new DirectoryPluginLoader(pluginsTestDir, DEFAULT_PLUGIN_FACTORIES, pluginEventManager);
  112. Iterable<Plugin> col = loader.loadFoundPlugins(moduleDescriptorFactory);
  113. assertFalse(Iterables.isEmpty(col));
  114. col = loader.loadFoundPlugins(moduleDescriptorFactory);
  115. assertTrue(Iterables.isEmpty(col));
  116. }
  117. @Test
  118. public void testFoundPlugin() throws PluginParseException, IOException {
  119. //delete paddington for the timebeing
  120. final File paddington = new File(pluginsTestDir + File.separator + PADDINGTON_JAR);
  121. paddington.delete();
  122. addTestModuleDecriptors();
  123. loader = new DirectoryPluginLoader(pluginsTestDir, DEFAULT_PLUGIN_FACTORIES, pluginEventManager);
  124. loader.loadAllPlugins(moduleDescriptorFactory);
  125. //restore paddington to test plugins dir
  126. FileUtils.copyDirectory(pluginsDirectory, pluginsTestDir);
  127. Iterable<Plugin> col = loader.loadFoundPlugins(moduleDescriptorFactory);
  128. assertEquals(1, Iterables.size(col));
  129. // next time we shouldn't find any new plugins
  130. col = loader.loadFoundPlugins(moduleDescriptorFactory);
  131. assertEquals(0, Iterables.size(col));
  132. }
  133. @Test
  134. public void testRemovePlugin() throws PluginException, IOException {
  135. addTestModuleDecriptors();
  136. loader = new DirectoryPluginLoader(pluginsTestDir, DEFAULT_PLUGIN_FACTORIES, pluginEventManager);
  137. final Iterable<Plugin> plugins = loader.loadAllPlugins(moduleDescriptorFactory);
  138. //duplicate the paddington plugin before removing the original
  139. //the duplicate will be used to restore the deleted original after the test
  140. final Iterator<Plugin> iter = plugins.iterator();
  141. Plugin paddingtonPlugin = null;
  142. while (iter.hasNext()) {
  143. final Plugin plugin = iter.next();
  144. if (plugin.getName().equals("Test Class Loaded Plugin")) {
  145. paddingtonPlugin = plugin;
  146. break;
  147. }
  148. }
  149. if (paddingtonPlugin == null) {
  150. fail("Can't find test plugin 1 (paddington)");
  151. }
  152. loader.removePlugin(paddingtonPlugin);
  153. }
  154. @Test
  155. public void testInvalidPluginHandled() throws IOException, PluginParseException {
  156. createJarFile("evilplugin.jar", PluginAccessor.Descriptor.FILENAME, pluginsTestDir.getAbsolutePath());
  157. loader = new DirectoryPluginLoader(pluginsTestDir, DEFAULT_PLUGIN_FACTORIES, pluginEventManager);
  158. final Iterable<Plugin> plugins = loader.loadAllPlugins(moduleDescriptorFactory);
  159. assertEquals("evil jar wasn't loaded, but other plugins were", pluginsTestDir.list(new FilenameFilter() {
  160. public boolean accept(final File directory, final String fileName) {
  161. return fileName.endsWith(".jar");
  162. }
  163. }).length, Iterables.size(plugins));
  164. assertEquals(1, Iterables.size(Iterables.filter(plugins, new Predicate<Plugin>() {
  165. @Override
  166. public boolean apply(final Plugin input) {
  167. return input instanceof UnloadablePlugin;
  168. }
  169. })));
  170. }
  171. @Test
  172. public void testInstallPluginTwice() throws URISyntaxException, IOException, PluginParseException, InterruptedException {
  173. FileUtils.cleanDirectory(pluginsTestDir);
  174. final File plugin = new File(pluginsTestDir, "some-plugin.jar");
  175. new PluginJarBuilder("plugin").addPluginInformation("some.key", "My name", "1.0", 1).addResource("foo.txt", "foo").build().renameTo(plugin);
  176. loader = new DirectoryPluginLoader(pluginsTestDir, DEFAULT_PLUGIN_FACTORIES, pluginEventManager);
  177. Iterable<Plugin> plugins = loader.loadAllPlugins(moduleDescriptorFactory);
  178. assertEquals(1, Iterables.size(plugins));
  179. assertNotNull((plugins.iterator().next()).getResource("foo.txt"));
  180. assertNull((plugins.iterator().next()).getResource("bar.txt"));
  181. Thread.currentThread();
  182. // sleep to ensure the new plugin is picked up
  183. Thread.sleep(1000);
  184. plugin.delete(); //delete the old plugin artifact to make windows happy
  185. new PluginJarBuilder("plugin").addPluginInformation("some.key", "My name", "1.0", 1).addResource("bar.txt", "bar").build().renameTo(plugin);
  186. plugins = loader.loadFoundPlugins(moduleDescriptorFactory);
  187. assertEquals(1, Iterables.size(plugins));
  188. assertNull((plugins.iterator().next()).getResource("foo.txt"));
  189. assertNotNull((plugins.iterator().next()).getResource("bar.txt"));
  190. assertTrue(plugin.exists());
  191. }
  192. @Test
  193. public void testMixedFactories() throws URISyntaxException, IOException, PluginParseException, InterruptedException {
  194. FileUtils.cleanDirectory(pluginsTestDir);
  195. final File plugin = new File(pluginsTestDir, "some-plugin.jar");
  196. new PluginJarBuilder("plugin").addPluginInformation("some.key", "My name", "1.0", 1).addResource("foo.txt", "foo").build().renameTo(plugin);
  197. FileUtils.writeStringToFile(new File(pluginsTestDir, "foo.xml"), "<atlassian-plugin key=\"jim\"></atlassian-plugin>");
  198. loader = new DirectoryPluginLoader(pluginsTestDir, DEFAULT_PLUGIN_FACTORIES, pluginEventManager);
  199. final Iterable<Plugin> plugins = loader.loadAllPlugins(moduleDescriptorFactory);
  200. assertEquals(2, Iterables.size(plugins));
  201. }
  202. @Test
  203. public void testUnknownPluginArtifact() throws URISyntaxException, IOException, PluginParseException, InterruptedException {
  204. FileUtils.cleanDirectory(pluginsTestDir);
  205. FileUtils.writeStringToFile(new File(pluginsTestDir, "foo.bob"), "<an>");
  206. loader = new DirectoryPluginLoader(pluginsTestDir, DEFAULT_PLUGIN_FACTORIES, pluginEventManager);
  207. final Iterable<Plugin> plugins = loader.loadAllPlugins(moduleDescriptorFactory);
  208. assertEquals(1, Iterables.size(plugins));
  209. assertTrue(plugins.iterator().next() instanceof UnloadablePlugin);
  210. }
  211. @Test
  212. public void testPluginWithModuleDescriptorWithNoKey() throws Exception, IOException, PluginParseException, InterruptedException {
  213. FileUtils.cleanDirectory(pluginsTestDir);
  214. new PluginJarBuilder("first")
  215. .addFormattedResource("atlassian-plugin.xml",
  216. "<atlassian-plugin name='Test' key='test.plugin'>",
  217. " <plugin-info>",
  218. " <version>1.0</version>",
  219. " </plugin-info>",
  220. " <object/>",
  221. "</atlassian-plugin>")
  222. .build(pluginsTestDir);
  223. loader = new DirectoryPluginLoader(pluginsTestDir, DEFAULT_PLUGIN_FACTORIES, pluginEventManager);
  224. final Iterable<Plugin> plugins = loader.loadAllPlugins(moduleDescriptorFactory);
  225. assertEquals(1, Iterables.size(plugins));
  226. assertTrue(plugins.iterator().next() instanceof UnloadablePlugin);
  227. assertEquals("test.plugin", plugins.iterator().next().getKey());
  228. }
  229. @Test
  230. public void testPluginWithBadDescriptor() throws Exception, IOException, PluginParseException, InterruptedException {
  231. FileUtils.cleanDirectory(pluginsTestDir);
  232. File pluginJar = new PluginJarBuilder("first")
  233. .addFormattedResource("atlassian-plugin.xml",
  234. "<atlassian-pluasdfasdf")
  235. .build(pluginsTestDir);
  236. loader = new DirectoryPluginLoader(pluginsTestDir, DEFAULT_PLUGIN_FACTORIES, pluginEventManager);
  237. final Iterable<Plugin> plugins = loader.loadAllPlugins(moduleDescriptorFactory);
  238. assertEquals(1, Iterables.size(plugins));
  239. assertTrue(plugins.iterator().next() instanceof UnloadablePlugin);
  240. assertEquals(pluginJar.getName(), plugins.iterator().next().getKey());
  241. }
  242. private void createJarFile(final String jarname, final String jarEntry, final String saveDir) throws IOException {
  243. final OutputStream os = new FileOutputStream(saveDir + File.separator + jarname);
  244. final JarOutputStream plugin1 = new JarOutputStream(os);
  245. final JarEntry jarEntry1 = new JarEntry(jarEntry);
  246. plugin1.putNextEntry(jarEntry1);
  247. plugin1.closeEntry();
  248. plugin1.flush();
  249. plugin1.close();
  250. }
  251. }