/atlassian-plugins-core/src/test/java/com/atlassian/plugin/loaders/TestScanningPluginLoader.java
Java | 545 lines | 435 code | 101 blank | 9 comment | 0 complexity | 5009c4028a88a4669402fd008814850c MD5 | raw file
- package com.atlassian.plugin.loaders;
- import com.atlassian.annotations.Internal;
- import com.atlassian.plugin.InstallationMode;
- import com.atlassian.plugin.ModuleDescriptor;
- import com.atlassian.plugin.ModuleDescriptorFactory;
- import com.atlassian.plugin.Plugin;
- import com.atlassian.plugin.PluginArtifact;
- import com.atlassian.plugin.PluginArtifactFactory;
- import com.atlassian.plugin.PluginDependencies;
- import com.atlassian.plugin.PluginException;
- import com.atlassian.plugin.PluginInformation;
- import com.atlassian.plugin.PluginState;
- import com.atlassian.plugin.Resourced;
- import com.atlassian.plugin.elements.ResourceDescriptor;
- import com.atlassian.plugin.elements.ResourceLocation;
- import com.atlassian.plugin.event.PluginEventManager;
- import com.atlassian.plugin.event.events.PluginFrameworkShutdownEvent;
- import com.atlassian.plugin.factories.PluginFactory;
- import com.atlassian.plugin.impl.UnloadablePlugin;
- import com.atlassian.plugin.loaders.classloading.DeploymentUnit;
- import com.atlassian.plugin.loaders.classloading.Scanner;
- import com.google.common.collect.Iterables;
- import org.dom4j.Element;
- import org.junit.Before;
- import org.junit.Rule;
- import org.junit.Test;
- import org.junit.rules.ExpectedException;
- import org.junit.runner.RunWith;
- import org.mockito.Mock;
- import org.mockito.junit.MockitoJUnitRunner;
- import javax.annotation.Nonnull;
- import javax.annotation.Nullable;
- import java.io.File;
- import java.io.InputStream;
- import java.net.URL;
- import java.util.Arrays;
- import java.util.Collection;
- import java.util.Collections;
- import java.util.Date;
- import java.util.List;
- import java.util.Optional;
- import java.util.Set;
- import static org.hamcrest.MatcherAssert.assertThat;
- import static org.hamcrest.Matchers.containsInAnyOrder;
- import static org.hamcrest.Matchers.is;
- import static org.hamcrest.Matchers.nullValue;
- import static org.junit.Assert.assertEquals;
- import static org.junit.Assert.assertNotNull;
- import static org.junit.Assert.assertNotSame;
- import static org.junit.Assert.assertSame;
- import static org.junit.Assert.assertTrue;
- import static org.junit.Assert.fail;
- import static org.mockito.ArgumentMatchers.any;
- import static org.mockito.Mockito.mock;
- import static org.mockito.Mockito.never;
- import static org.mockito.Mockito.verify;
- import static org.mockito.Mockito.when;
- @RunWith(MockitoJUnitRunner.Silent.class)
- public class TestScanningPluginLoader {
- private static final String PLUGIN_KEY = "plugin-key";
- @Rule
- public final ExpectedException expectedException = ExpectedException.none();
- @Mock
- private PluginArtifactFactory pluginArtifactFactory;
- @Mock
- private PluginArtifact pluginArtifact;
- @Mock
- private PluginFactory pluginFactory;
- @Mock
- private ModuleDescriptorFactory moduleDescriptorFactory;
- @Mock
- private Plugin plugin;
- @Mock
- private Scanner scanner;
- @Mock
- private PluginEventManager pluginEventManager;
- @Mock
- private Element module;
- private DeploymentUnit deploymentUnit;
- @Before
- public void configureMocks() {
- deploymentUnit = new DeploymentUnit(new File("foo.jar"));
- when(plugin.getKey()).thenReturn(PLUGIN_KEY);
- when(pluginArtifactFactory.create(deploymentUnit.getPath().toURI())).thenReturn(pluginArtifact);
- when(pluginFactory.canCreate(pluginArtifact)).thenReturn("foo");
- when(scanner.getDeploymentUnits()).thenReturn(Arrays.asList(deploymentUnit));
- }
- @Test
- public void loadAllPluginsLoadsPlugin() {
- when(pluginFactory.create(pluginArtifact, moduleDescriptorFactory)).thenReturn(plugin);
- final ScanningPluginLoader loader = buildScanningPluginLoader();
- final Iterable<Plugin> plugins = loader.loadAllPlugins(moduleDescriptorFactory);
- assertThat(plugins, containsInAnyOrder(plugin));
- }
- @Test
- public void removeEnabledPluginFails() {
- when(plugin.getPluginState()).thenReturn(PluginState.ENABLED);
- final ScanningPluginLoader loader = buildScanningPluginLoader();
- expectedException.expect(PluginException.class);
- expectedException.expectMessage(PLUGIN_KEY);
- loader.removePlugin(plugin);
- }
- @Test
- public void removeNotUninstallablePluginFails() {
- when(plugin.isUninstallable()).thenReturn(false);
- final ScanningPluginLoader loader = buildScanningPluginLoader();
- expectedException.expect(PluginException.class);
- expectedException.expectMessage(PLUGIN_KEY);
- loader.removePlugin(plugin);
- }
- @Test
- public void removeDeleteablePluginDoesUninstallAndDelete() {
- when(plugin.isUninstallable()).thenReturn(true);
- when(plugin.isDeleteable()).thenReturn(true);
- when(pluginFactory.create(pluginArtifact, moduleDescriptorFactory)).thenReturn(plugin);
- final ScanningPluginLoader loader = buildScanningPluginLoader();
- final Iterable<Plugin> plugins = loader.loadAllPlugins(moduleDescriptorFactory);
- assertThat(plugins, containsInAnyOrder(plugin));
- loader.removePlugin(plugin);
- verify(plugin).uninstall();
- verify(scanner).remove(deploymentUnit);
- }
- @Test
- public void removeNotDeleteablePluginDoesUninstallButDoesntDelete() {
- when(plugin.isUninstallable()).thenReturn(true);
- when(plugin.isDeleteable()).thenReturn(false);
- when(pluginFactory.create(pluginArtifact, moduleDescriptorFactory)).thenReturn(plugin);
- final ScanningPluginLoader loader = buildScanningPluginLoader();
- final Iterable<Plugin> plugins = loader.loadAllPlugins(moduleDescriptorFactory);
- assertThat(plugins, containsInAnyOrder(plugin));
- loader.removePlugin(plugin);
- verify(plugin).uninstall();
- verify(scanner, never()).remove(any(DeploymentUnit.class));
- }
- @Test
- public void discardedPluginIsNotTracked() {
- when(plugin.isUninstallable()).thenReturn(true);
- when(pluginFactory.create(pluginArtifact, moduleDescriptorFactory)).thenReturn(plugin);
- final ScanningPluginLoader loader = buildScanningPluginLoader();
- final Iterable<Plugin> plugins = loader.loadAllPlugins(moduleDescriptorFactory);
- assertThat(plugins, containsInAnyOrder(plugin));
- loader.discardPlugin(plugin);
- try {
- // Discarded, so removal should fail even though isUninstallable
- loader.removePlugin(plugin);
- fail();
- } catch (final PluginException pe) {
- // Expected
- }
- // Shutdown should not result in uninstall of discarded plugin
- loader.onShutdown(mock(PluginFrameworkShutdownEvent.class));
- verify(plugin, never()).uninstall();
- }
- @Test
- public void shutdownUninstallsUninstallablePlugin() {
- when(plugin.isUninstallable()).thenReturn(true);
- when(pluginFactory.create(pluginArtifact, moduleDescriptorFactory)).thenReturn(plugin);
- final ScanningPluginLoader loader = buildScanningPluginLoader();
- loader.loadAllPlugins(moduleDescriptorFactory);
- loader.onShutdown(mock(PluginFrameworkShutdownEvent.class));
- verify(plugin).uninstall();
- }
- @Test
- public void shutdownDoesNotUninstallNotUninstallablePlugin() {
- when(plugin.isUninstallable()).thenReturn(false);
- when(pluginFactory.create(pluginArtifact, moduleDescriptorFactory)).thenReturn(plugin);
- final ScanningPluginLoader loader = buildScanningPluginLoader();
- loader.loadAllPlugins(moduleDescriptorFactory);
- loader.onShutdown(mock(PluginFrameworkShutdownEvent.class));
- verify(plugin, never()).uninstall();
- }
- @Test
- public void factoryThrowingRuntimeExceptionYieldsUnloadablePlugin() {
- factoryThrowingYieldsUnloadablePlugin(new IllegalArgumentException());
- }
- @Test
- public void factoryThrowingErrorYieldsUnloadablePlugin() {
- factoryThrowingYieldsUnloadablePlugin(new NoClassDefFoundError());
- }
- private void factoryThrowingYieldsUnloadablePlugin(final Throwable throwable) {
- when(pluginFactory.create(pluginArtifact, moduleDescriptorFactory)).thenThrow(throwable);
- final ScanningPluginLoader loader = buildScanningPluginLoader();
- final Iterable<Plugin> plugins = loader.loadAllPlugins(moduleDescriptorFactory);
- assertNotNull(plugins);
- assertEquals(1, Iterables.size(plugins));
- assertTrue(Iterables.getOnlyElement(plugins) instanceof UnloadablePlugin);
- }
- @Test
- public void pluginLoaderCallsPostProcess() {
- when(plugin.isUninstallable()).thenReturn(true);
- when(pluginFactory.create(pluginArtifact, moduleDescriptorFactory)).thenReturn(plugin);
- final ScanningPluginLoader loader = new ScanningPluginLoader(
- scanner, Collections.singletonList(pluginFactory), pluginArtifactFactory, pluginEventManager) {
- @Override
- protected Plugin postProcess(final Plugin plugin) {
- return new WrappedPlugin(plugin);
- }
- };
- final Iterable<Plugin> allPlugins = loader.loadAllPlugins(moduleDescriptorFactory);
- assertPluginsIsWrapperFor(allPlugins, plugin);
- final DeploymentUnit unitB = new DeploymentUnit(new File("bar.jar"));
- final PluginArtifact pluginArtifactB = mock(PluginArtifact.class);
- final Plugin pluginB = mock(Plugin.class);
- when(scanner.scan()).thenReturn(Arrays.asList(unitB));
- when(pluginArtifactFactory.create(unitB.getPath().toURI())).thenReturn(pluginArtifactB);
- when(pluginFactory.canCreate(pluginArtifactB)).thenReturn("bar");
- when(pluginFactory.create(pluginArtifactB, moduleDescriptorFactory)).thenReturn(pluginB);
- final Iterable<Plugin> foundPlugins = loader.loadFoundPlugins(moduleDescriptorFactory);
- assertPluginsIsWrapperFor(foundPlugins, pluginB);
- }
- @Test
- public void createModule() {
- final ModuleDescriptor moduleDescriptor = mock(ModuleDescriptor.class);
- final ScanningPluginLoader scanningPluginLoader = buildScanningPluginLoader();
- when(pluginFactory.createModule(plugin, module, moduleDescriptorFactory)).thenReturn(moduleDescriptor);
- assertThat(scanningPluginLoader.createModule(plugin, module, moduleDescriptorFactory), is(moduleDescriptor));
- }
- @Test
- public void createModuleNoFactory() {
- final ScanningPluginLoader scanningPluginLoader = buildScanningPluginLoader();
- when(pluginFactory.createModule(plugin, module, moduleDescriptorFactory)).thenReturn(null);
- assertThat(scanningPluginLoader.createModule(plugin, module, moduleDescriptorFactory), nullValue());
- }
- /**
- * A wrapper class for the postProcess test.
- *
- * By using a wrapper here, we guarantee postProcess is called, because no one else
- * could have an instance of this private class.
- */
- private static class WrappedPlugin implements Plugin {
- private final Plugin delegate;
- public WrappedPlugin(final Plugin plugin) {
- delegate = plugin;
- }
- @Override
- public int getPluginsVersion() {
- return delegate.getPluginsVersion();
- }
- @Override
- public void setPluginsVersion(int version) {
- delegate.setPluginsVersion(version);
- }
- @Override
- public String getName() {
- return delegate.getName();
- }
- @Override
- public void setName(String name) {
- delegate.setName(name);
- }
- @Override
- public String getI18nNameKey() {
- return delegate.getI18nNameKey();
- }
- @Override
- public void setI18nNameKey(String i18nNameKey) {
- delegate.setI18nNameKey(i18nNameKey);
- }
- @Override
- public String getKey() {
- return delegate.getKey();
- }
- @Override
- public void setKey(String aPackage) {
- delegate.setKey(aPackage);
- }
- @Override
- public void addModuleDescriptor(ModuleDescriptor<?> moduleDescriptor) {
- delegate.addModuleDescriptor(moduleDescriptor);
- }
- @Override
- public Collection<ModuleDescriptor<?>> getModuleDescriptors() {
- return delegate.getModuleDescriptors();
- }
- @Override
- public ModuleDescriptor<?> getModuleDescriptor(String key) {
- return delegate.getModuleDescriptor(key);
- }
- @Override
- public <M> List<ModuleDescriptor<M>> getModuleDescriptorsByModuleClass(Class<M> moduleClass) {
- return delegate.getModuleDescriptorsByModuleClass(moduleClass);
- }
- @Override
- public InstallationMode getInstallationMode() {
- return delegate.getInstallationMode();
- }
- @Override
- public boolean isEnabledByDefault() {
- return delegate.isEnabledByDefault();
- }
- @Override
- public void setEnabledByDefault(boolean enabledByDefault) {
- delegate.setEnabledByDefault(enabledByDefault);
- }
- @Override
- public PluginInformation getPluginInformation() {
- return delegate.getPluginInformation();
- }
- @Override
- public void setPluginInformation(PluginInformation pluginInformation) {
- delegate.setPluginInformation(pluginInformation);
- }
- @Override
- public void setResources(Resourced resources) {
- delegate.setResources(resources);
- }
- @Override
- public PluginState getPluginState() {
- return delegate.getPluginState();
- }
- @Override
- public boolean isSystemPlugin() {
- return delegate.isSystemPlugin();
- }
- @Override
- public void setSystemPlugin(boolean system) {
- delegate.setSystemPlugin(system);
- }
- @Override
- public boolean containsSystemModule() {
- return delegate.containsSystemModule();
- }
- @Override
- public boolean isBundledPlugin() {
- return delegate.isBundledPlugin();
- }
- @Override
- public Date getDateLoaded() {
- return delegate.getDateLoaded();
- }
- @Override
- public Date getDateInstalled() {
- return delegate.getDateInstalled();
- }
- @Override
- public boolean isUninstallable() {
- return delegate.isUninstallable();
- }
- @Override
- public boolean isDeleteable() {
- return delegate.isDeleteable();
- }
- @Override
- public boolean isDynamicallyLoaded() {
- return delegate.isDynamicallyLoaded();
- }
- @Override
- public <T> Class<T> loadClass(String clazz, Class<?> callingClass) throws ClassNotFoundException {
- return delegate.loadClass(clazz, callingClass);
- }
- @Override
- public ClassLoader getClassLoader() {
- return delegate.getClassLoader();
- }
- @Override
- public URL getResource(String path) {
- return delegate.getResource(path);
- }
- @Override
- public InputStream getResourceAsStream(String name) {
- return delegate.getResourceAsStream(name);
- }
- @Override
- public void install() {
- delegate.install();
- }
- @Override
- public void uninstall() {
- delegate.uninstall();
- }
- @Override
- public void enable() {
- delegate.enable();
- }
- @Override
- public void disable() {
- delegate.disable();
- }
- @Override
- @Nonnull
- public PluginDependencies getDependencies() {
- return delegate.getDependencies();
- }
- @Override
- public Set<String> getActivePermissions() {
- return delegate.getActivePermissions();
- }
- @Override
- public boolean hasAllPermissions() {
- return delegate.hasAllPermissions();
- }
- @Override
- public void resolve() {
- delegate.resolve();
- }
- @Override
- @Nullable
- public Date getDateEnabling() {
- return delegate.getDateEnabling();
- }
- @Override
- @Nullable
- public Date getDateEnabled() {
- return delegate.getDateEnabled();
- }
- @Override
- @Internal
- public PluginArtifact getPluginArtifact() {
- return delegate.getPluginArtifact();
- }
- @Override
- public Optional<String> getScopeKey() {
- return delegate.getScopeKey();
- }
- @Override
- public List<ResourceDescriptor> getResourceDescriptors() {
- return delegate.getResourceDescriptors();
- }
- @Override
- public ResourceDescriptor getResourceDescriptor(String type, String name) {
- return delegate.getResourceDescriptor(type, name);
- }
- @Override
- public ResourceLocation getResourceLocation(String type, String name) {
- return delegate.getResourceLocation(type, name);
- }
- @Override
- public int compareTo(Plugin o) {
- return delegate.compareTo(o);
- }
- }
- private void assertPluginsIsWrapperFor(final Iterable<Plugin> plugins, final Plugin originalPlugin) {
- assertNotNull(plugins);
- assertEquals(1, Iterables.size(plugins));
- final Plugin loadedPlugin = Iterables.getOnlyElement(plugins);
- assertNotSame(loadedPlugin, originalPlugin);
- assertTrue(loadedPlugin instanceof WrappedPlugin);
- final WrappedPlugin wrappedPlugin = (WrappedPlugin) loadedPlugin;
- assertSame(wrappedPlugin.delegate, originalPlugin);
- }
- private ScanningPluginLoader buildScanningPluginLoader() {
- return new ScanningPluginLoader(scanner, Collections.singletonList(pluginFactory), pluginArtifactFactory, pluginEventManager);
- }
- }