/*
* Copyright 2017 ThoughtWorks, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.thoughtworks.go.plugin.infra.listeners;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Arrays;
import com.thoughtworks.go.util.SystemEnvironment;
import com.thoughtworks.go.plugin.api.info.PluginDescriptorAware;
import com.thoughtworks.go.plugin.infra.Action;
import com.thoughtworks.go.plugin.infra.ExceptionHandler;
import com.thoughtworks.go.plugin.infra.GoPluginFrameworkException;
import com.thoughtworks.go.plugin.infra.GoPluginOSGiFramework;
import com.thoughtworks.go.plugin.infra.monitor.PluginFileDetails;
import com.thoughtworks.go.plugin.infra.plugininfo.DefaultPluginRegistry;
import com.thoughtworks.go.plugin.infra.plugininfo.GoPluginDescriptor;
import com.thoughtworks.go.plugin.infra.plugininfo.GoPluginDescriptorBuilder;
import com.thoughtworks.go.plugin.infra.plugininfo.GoPluginOSGiManifest;
import com.thoughtworks.go.plugin.infra.plugininfo.GoPluginOSGiManifestGenerator;
import org.apache.commons.io.FileUtils;
import org.hamcrest.CoreMatchers;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Matchers;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.osgi.framework.Bundle;
import static com.thoughtworks.go.util.SystemEnvironment.PLUGIN_ACTIVATOR_JAR_PATH;
import static com.thoughtworks.go.util.SystemEnvironment.PLUGIN_BUNDLE_PATH;
import static java.util.Arrays.asList;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
public class DefaultPluginJarChangeListenerTest {
private static final String TEST_BUNDLES_DIR = "test-bundles-dir";
private static final String TEST_PLUGINS_DIR = "test-plugins-dir";
private File PLUGIN_DIR;
private File BUNDLE_DIR;
private DefaultPluginRegistry registry;
private GoPluginOSGiManifestGenerator osgiManifestGenerator;
private DefaultPluginJarChangeListener listener;
private GoPluginOSGiFramework osgiFramework;
private SystemEnvironment systemEnvironment;
private GoPluginDescriptorBuilder goPluginDescriptorBuilder;
@Before
public void setUp() throws Exception {
BUNDLE_DIR = new File(TEST_BUNDLES_DIR);
PLUGIN_DIR = new File(TEST_PLUGINS_DIR);
registry = mock(DefaultPluginRegistry.class);
osgiManifestGenerator = mock(GoPluginOSGiManifest.DefaultGoPluginOSGiManifestCreator.class);
osgiFramework = mock(GoPluginOSGiFramework.class);
goPluginDescriptorBuilder = mock(GoPluginDescriptorBuilder.class);
systemEnvironment = mock(SystemEnvironment.class);
when(systemEnvironment.get(PLUGIN_ACTIVATOR_JAR_PATH)).thenReturn("defaultFiles/go-plugin-activator.jar");
when(systemEnvironment.get(PLUGIN_BUNDLE_PATH)).thenReturn(TEST_BUNDLES_DIR);
when(systemEnvironment.getOperatingSystemFamilyName()).thenReturn("Linux");
listener = new DefaultPluginJarChangeListener(registry, osgiManifestGenerator, osgiFramework, goPluginDescriptorBuilder, systemEnvironment);
}
@After
public void tearDown() throws Exception {
FileUtils.deleteQuietly(PLUGIN_DIR);
FileUtils.deleteQuietly(BUNDLE_DIR);
}
@Test
public void shouldCopyPluginToBundlePathAndInformRegistryAndUpdateTheOSGiManifestWhenAPluginIsAdded() throws Exception {
String pluginId = "testplugin.descriptorValidator";
String pluginJarFileName = "descriptor-aware-test-plugin.jar";
File pluginJarFile = new File(PLUGIN_DIR, pluginJarFileName);
File expectedBundleDirectory = new File(TEST_BUNDLES_DIR, pluginJarFileName);
copyPluginToTheDirectory(PLUGIN_DIR, pluginJarFileName);
GoPluginDescriptor descriptor = GoPluginDescriptor.usingId(pluginId, pluginJarFile.getAbsolutePath(), expectedBundleDirectory, true);
when(goPluginDescriptorBuilder.build(pluginJarFile, true)).thenReturn(descriptor);
when(registry.getPluginByIdOrFileName(pluginId, pluginJarFileName)).thenReturn(null);
doNothing().when(registry).loadPlugin(descriptor);
listener.pluginJarAdded(new PluginFileDetails(pluginJarFile, true));
assertThat(expectedBundleDirectory.exists(), is(true));
verify(registry).getPluginByIdOrFileName(pluginId, pluginJarFileName);
verify(registry).loadPlugin(descriptor);
verify(osgiManifestGenerator).updateManifestOf(descriptor);
verify(osgiFramework).loadPlugin(descriptor);
verifyNoMoreInteractions(osgiManifestGenerator);
verifyNoMoreInteractions(registry);
assertThat(new File(expectedBundleDirectory, "lib/go-plugin-activator.jar").exists(), is(true));
}
@Test
public void shouldOverwriteAFileCalledGoPluginActivatorInLibWithOurOwnGoPluginActivatorEvenIfItExists() throws Exception {
String pluginJarFileName = "descriptor-aware-test-plugin.jar";
File pluginJarFile = new File(PLUGIN_DIR, pluginJarFileName);
File expectedBundleDirectory = new File(TEST_BUNDLES_DIR, pluginJarFileName);
File activatorFileLocation = new File(expectedBundleDirectory, "lib/go-plugin-activator.jar");
FileUtils.writeStringToFile(activatorFileLocation, "SOME-DATA");
copyPluginToTheDirectory(PLUGIN_DIR, pluginJarFileName);
GoPluginDescriptor descriptor = GoPluginDescriptor.usingId("testplugin.descriptorValidator", pluginJarFile.getAbsolutePath(), expectedBundleDirectory, true);
when(goPluginDescriptorBuilder.build(pluginJarFile, true)).thenReturn(descriptor);
doNothing().when(registry).loadPlugin(descriptor);
listener.pluginJarAdded(new PluginFileDetails(pluginJarFile, true));
assertThat(new File(expectedBundleDirectory, "lib/go-plugin-activator.jar").exists(), is(true));
assertThat(FileUtils.readFileToString(activatorFileLocation), is(not("SOME-DATA")));
}
@Test
public void shouldCopyPluginToBundlePathAndInformRegistryAndUpdateTheOSGiManifestWhenAPluginIsUpdated() throws Exception {
DefaultPluginJarChangeListener spy = spy(listener);
String pluginId = "plugin-id";
String pluginJarFileName = "jarName";
File pluginJarFile = mock(File.class);
File oldPluginBundleDirectory = new File(TEST_BUNDLES_DIR, "old-bundle");
FileUtils.forceMkdir(oldPluginBundleDirectory);
final File explodedDirectory = mock(File.class);
doNothing().when(spy).explodePluginJarToBundleDir(pluginJarFile, explodedDirectory);
doNothing().when(spy).installActivatorJarToBundleDir(explodedDirectory);
GoPluginDescriptor oldDescriptor = mock(GoPluginDescriptor.class);
Bundle oldBundle = mock(Bundle.class);
when(oldDescriptor.bundle()).thenReturn(oldBundle);
when(oldDescriptor.fileName()).thenReturn(pluginJarFileName);
when(oldDescriptor.bundleLocation()).thenReturn(oldPluginBundleDirectory);
GoPluginDescriptor newDescriptor = mock(GoPluginDescriptor.class);
when(newDescriptor.id()).thenReturn(pluginId);
when(newDescriptor.isInvalid()).thenReturn(false);
when(newDescriptor.bundleLocation()).thenReturn(explodedDirectory);
when(newDescriptor.fileName()).thenReturn(pluginJarFileName);
when(newDescriptor.isCurrentOSValidForThisPlugin(systemEnvironment.getOperatingSystemFamilyName())).thenReturn(true);
when(goPluginDescriptorBuilder.build(pluginJarFile, true)).thenReturn(newDescriptor);
when(registry.getPluginByIdOrFileName(pluginId, pluginJarFileName)).thenReturn(oldDescriptor);
when(registry.unloadPlugin(newDescriptor)).thenReturn(oldDescriptor);
doNothing().when(registry).loadPlugin(newDescriptor);
spy.pluginJarUpdated(new PluginFileDetails(pluginJarFile, true));
assertThat(oldPluginBundleDirectory.exists(), is(false));
verify(registry).getPluginByIdOrFileName(pluginId, pluginJarFileName);
verify(registry).unloadPlugin(newDescriptor);
verify(registry).loadPlugin(newDescriptor);
verify(osgiManifestGenerator).updateManifestOf(newDescriptor);
verify(osgiFramework).unloadPlugin(oldDescriptor);
verify(osgiFramework).loadPlugin(newDescriptor);
verifyNoMoreInteractions(osgiManifestGenerator);
verifyNoMoreInteractions(registry);
}
@Test
public void shouldRemovePluginFromBundlePathAndInformRegistryWhenAPluginIsRemoved() throws Exception {
String pluginJarFileName = "descriptor-aware-test-plugin.jar";
File pluginJarFile = new File(PLUGIN_DIR, pluginJarFileName);
File removedBundleDirectory = new File(BUNDLE_DIR, pluginJarFileName);
Bundle bundle = mock(Bundle.class);
GoPluginDescriptor descriptorOfThePluginWhichWillBeRemoved = GoPluginDescriptor.usingId("testplugin.descriptorValidator", pluginJarFile.getAbsolutePath(), removedBundleDirectory, true);
descriptorOfThePluginWhichWillBeRemoved.setBundle(bundle);
when(registry.getPluginByIdOrFileName(null,descriptorOfThePluginWhichWillBeRemoved.fileName())).thenReturn(descriptorOfThePluginWhichWillBeRemoved);
when(registry.unloadPlugin(descriptorOfThePluginWhichWillBeRemoved)).thenReturn(descriptorOfThePluginWhichWillBeRemoved);
copyPluginToTheDirectory(BUNDLE_DIR, pluginJarFileName);
listener.pluginJarRemoved(new PluginFileDetails(pluginJarFile, true));
verify(registry).unloadPlugin(descriptorOfThePluginWhichWillBeRemoved);
verify(osgiFramework).unloadPlugin(descriptorOfThePluginWhichWillBeRemoved);
assertThat(removedBundleDirectory.exists(), is(false));
}
@Test
public void shouldNotTryAndUpdateManifestOfAnAddedInvalidPlugin() throws Exception {
String pluginJarFileName = "descriptor-aware-test-plugin.jar";
File pluginJarFile = new File(PLUGIN_DIR, pluginJarFileName);
copyPluginToTheDirectory(PLUGIN_DIR, pluginJarFileName);
File expectedBundleDirectory = new File(TEST_BUNDLES_DIR, pluginJarFileName);
GoPluginDescriptor descriptorForInvalidPlugin = GoPluginDescriptor.usingId("testplugin.descriptorValidator", pluginJarFile.getAbsolutePath(), expectedBundleDirectory, true).markAsInvalid(
asList("For a test"), null);
when(goPluginDescriptorBuilder.build(pluginJarFile, true)).thenReturn(descriptorForInvalidPlugin);
doNothing().when(registry).loadPlugin(descriptorForInvalidPlugin);
listener.pluginJarAdded(new PluginFileDetails(pluginJarFile, true));
assertThat(expectedBundleDirectory.exists(), is(true));
verify(registry).loadPlugin(descriptorForInvalidPlugin);
verifyNoMoreInteractions(osgiManifestGenerator);
}
@Test
public void shouldNotTryAndUpdateManifestOfAnUpdatedInvalidPlugin() throws Exception {
DefaultPluginJarChangeListener spy = spy(listener);
String pluginId = "plugin-id";
String pluginJarFileName = "descriptor-aware-test-plugin.jar";
File pluginFile = new File(PLUGIN_DIR, pluginJarFileName);
copyPluginToTheDirectory(PLUGIN_DIR, pluginJarFileName);
File expectedBundleDirectoryForInvalidPlugin = new File(TEST_BUNDLES_DIR, pluginJarFileName);
File bundleDirectoryForOldPlugin = new File(TEST_BUNDLES_DIR, "descriptor-aware-test-plugin-old.jar");
FileUtils.forceMkdir(bundleDirectoryForOldPlugin);
GoPluginDescriptor descriptorForInvalidPlugin = GoPluginDescriptor.usingId("testplugin.descriptorValidator", pluginFile.getAbsolutePath(), expectedBundleDirectoryForInvalidPlugin,
true).markAsInvalid(
asList("For a test"), null);
Bundle oldBundle = mock(Bundle.class);
GoPluginDescriptor oldPluginDescriptor = GoPluginDescriptor.usingId("some.old.id", "some/path/to/plugin.jar", bundleDirectoryForOldPlugin, true).setBundle(oldBundle);
when(goPluginDescriptorBuilder.build(pluginFile, true)).thenReturn(descriptorForInvalidPlugin);
when(registry.getPlugin(pluginId)).thenReturn(oldPluginDescriptor);
when(registry.unloadPlugin(descriptorForInvalidPlugin)).thenReturn(oldPluginDescriptor);
doNothing().when(registry).loadPlugin(descriptorForInvalidPlugin);
spy.pluginJarUpdated(new PluginFileDetails(pluginFile, true));
assertThat(expectedBundleDirectoryForInvalidPlugin.exists(), CoreMatchers.is(true));
assertThat(bundleDirectoryForOldPlugin.exists(), CoreMatchers.is(false));
verify(registry).unloadPlugin(descriptorForInvalidPlugin);
verify(osgiFramework).unloadPlugin(oldPluginDescriptor);
verify(registry).loadPlugin(descriptorForInvalidPlugin);
verifyNoMoreInteractions(osgiManifestGenerator);
verifyNoMoreInteractions(osgiFramework);
}
@Test(expected = RuntimeException.class)
public void shouldFailToLoadAPluginWhenActivatorJarIsNotAvailable() throws Exception {
systemEnvironment = mock(SystemEnvironment.class);
when(systemEnvironment.get(PLUGIN_ACTIVATOR_JAR_PATH)).thenReturn("some-path-which-does-not-exist.jar");
String pluginJarFileName = "descriptor-aware-test-plugin.jar";
File pluginJarFile = new File(PLUGIN_DIR, pluginJarFileName);
File bundleDirectory = new File(TEST_BUNDLES_DIR, pluginJarFileName);
copyPluginToTheDirectory(PLUGIN_DIR, pluginJarFileName);
GoPluginDescriptor descriptor = GoPluginDescriptor.usingId("some.old.id", pluginJarFile.getAbsolutePath(), bundleDirectory, true);
when(goPluginDescriptorBuilder.build(pluginJarFile, true)).thenReturn(descriptor);
listener = new DefaultPluginJarChangeListener(registry, osgiManifestGenerator, osgiFramework, goPluginDescriptorBuilder, systemEnvironment);
listener.pluginJarAdded(new PluginFileDetails(pluginJarFile, true));
}
@Test
public void shouldNotReplaceBundledPluginWhenExternalPluginIsAdded() throws Exception {
String pluginId = "external";
String pluginJarFileName = "plugin-file-name";
File pluginJarFile = mock(File.class);
when(pluginJarFile.getName()).thenReturn(pluginJarFileName);
GoPluginDescriptor externalPluginDescriptor = new GoPluginDescriptor(pluginId, "1.0", null, pluginJarFile.getAbsolutePath(), new File(pluginJarFileName), false);
when(goPluginDescriptorBuilder.build(pluginJarFile, false)).thenReturn(externalPluginDescriptor);
GoPluginDescriptor bundledPluginDescriptor = new GoPluginDescriptor("bundled", "1.0", null, null, null, true);
when(registry.getPluginByIdOrFileName(pluginId, pluginJarFileName)).thenReturn(bundledPluginDescriptor);
DefaultPluginJarChangeListener spy = spy(listener);
try {
listener.pluginJarAdded(new PluginFileDetails(pluginJarFile, false));
fail("should have failed as external plugin cannot replace bundled plugin");
} catch (RuntimeException e) {
assertThat(e.getMessage(), is("Found bundled plugin with ID: [bundled], external plugin could not be loaded"));
}
verify(spy, never()).explodePluginJarToBundleDir(pluginJarFile, externalPluginDescriptor.bundleLocation());
}
@Test
public void shouldNotUpdatePluginWhenThereIsExistingPluginWithSameId() throws Exception {
String pluginId = "plugin-id";
String pluginJarFileName = "plugin-file-name";
File pluginJarFile = mock(File.class);
when(pluginJarFile.getName()).thenReturn(pluginJarFileName);
GoPluginDescriptor newPluginDescriptor = new GoPluginDescriptor(pluginId, "1.0", null, pluginJarFile.getAbsolutePath(), new File(pluginJarFileName), true);
when(goPluginDescriptorBuilder.build(pluginJarFile, false)).thenReturn(newPluginDescriptor);
GoPluginDescriptor oldPluginDescriptor = new GoPluginDescriptor(pluginId, "1.0", null, "location-old", new File("location-old"), true);
when(registry.getPluginByIdOrFileName(pluginId, pluginJarFileName)).thenReturn(oldPluginDescriptor);
DefaultPluginJarChangeListener spy = spy(listener);
try {
spy.pluginJarUpdated(new PluginFileDetails(pluginJarFile, false));
fail("should have failed as external plugin cannot replace bundled plugin");
} catch (RuntimeException e) {
assertThat(e.getMessage(), is("Found another plugin with ID: plugin-id"));
}
verify(spy, never()).explodePluginJarToBundleDir(pluginJarFile, newPluginDescriptor.bundleLocation());
}
@Test
public void shouldNotUpdateBundledPluginWithExternalPlugin() throws Exception {
String pluginId = "plugin-id";
String pluginJarFileName = "plugin-file-name";
File pluginJarFile = mock(File.class);
when(pluginJarFile.getName()).thenReturn(pluginJarFileName);
GoPluginDescriptor newPluginDescriptor = new GoPluginDescriptor(pluginId, "1.0", null, null, new File(pluginJarFileName), false);
when(goPluginDescriptorBuilder.build(pluginJarFile, false)).thenReturn(newPluginDescriptor);
GoPluginDescriptor oldPluginDescriptor = new GoPluginDescriptor(pluginId, "1.0", null, null, null, true);
when(registry.getPluginByIdOrFileName(pluginId, pluginJarFileName)).thenReturn(oldPluginDescriptor);
DefaultPluginJarChangeListener spy = spy(listener);
try {
spy.pluginJarUpdated(new PluginFileDetails(pluginJarFile, false));
fail("should have failed as external plugin cannot replace bundled plugin");
} catch (RuntimeException e) {
assertThat(e.getMessage(), is("Found bundled plugin with ID: [plugin-id], external plugin could not be loaded"));
}
verify(spy, never()).explodePluginJarToBundleDir(pluginJarFile, newPluginDescriptor.bundleLocation());
}
@Test
public void shouldNotRemoveBundledPluginExternalPluginJarRemovedWithSameId() throws Exception {
String pluginId = "plugin-id";
String pluginJarFileName = "plugin-file-name";
File pluginJarFile = mock(File.class);
when(pluginJarFile.getName()).thenReturn(pluginJarFileName);
GoPluginDescriptor oldPluginDescriptor = new GoPluginDescriptor(pluginId, "1.0", null, null, null, true);
when(registry.getPluginByIdOrFileName(null, pluginJarFileName)).thenReturn(oldPluginDescriptor);
DefaultPluginJarChangeListener spy = spy(listener);
spy.pluginJarRemoved(new PluginFileDetails(pluginJarFile, false));
verify(registry, never()).unloadPlugin(oldPluginDescriptor);
verify(osgiFramework, never()).unloadPlugin(oldPluginDescriptor);
}
@Test
public void shouldNotLoadAPluginWhenCurrentOSIsNotAmongTheListOfTargetOSesAsDeclaredByThePluginInItsXML() throws Exception {
String pluginJarFileName = "descriptor-aware-test-plugin.jar";
File pluginJarFile = new File(PLUGIN_DIR, pluginJarFileName);
copyPluginToTheDirectory(PLUGIN_DIR, pluginJarFileName);
GoPluginDescriptor descriptor = new GoPluginDescriptor("some.old.id", "1.0", new GoPluginDescriptor.About(null, null, null, null, null, asList("Linux", "Mac OS X")), null,
new File(pluginJarFileName), false);
when(systemEnvironment.getOperatingSystemFamilyName()).thenReturn("Windows");
when(goPluginDescriptorBuilder.build(pluginJarFile, true)).thenReturn(descriptor);
listener = new DefaultPluginJarChangeListener(registry, osgiManifestGenerator, osgiFramework, goPluginDescriptorBuilder, systemEnvironment);
listener.pluginJarAdded(new PluginFileDetails(pluginJarFile, true));
verify(registry, times(1)).loadPlugin(descriptor);
verifyZeroInteractions(osgiFramework);
assertThat(descriptor.getStatus().getMessages().size(), is(1));
assertThat(descriptor.getStatus().getMessages().get(0),
is("Plugin with ID (some.old.id) is not valid: Incompatible with current operating system 'Windows'. Valid operating systems are: [Linux, Mac OS X]."));
}
@Test
public void shouldNotLoadAPluginWhenCurrentOSIsNotAmongTheListOfTargetOSesAsDeclaredByThePluginInItsXMLForUpdatePath() throws Exception {
String pluginJarFileName = "descriptor-aware-test-plugin.jar";
File pluginJarFile = new File(PLUGIN_DIR, pluginJarFileName);
copyPluginToTheDirectory(PLUGIN_DIR, pluginJarFileName);
String pluginID = "some.id";
GoPluginDescriptor newPluginDescriptor = new GoPluginDescriptor(pluginID, "1.0", new GoPluginDescriptor.About(null, null, null, null, null, asList("Mac OS X")), null,
new File(pluginJarFileName), true);
when(goPluginDescriptorBuilder.build(pluginJarFile, false)).thenReturn(newPluginDescriptor);
GoPluginDescriptor oldPluginDescriptor = new GoPluginDescriptor(pluginID, "1.0", new GoPluginDescriptor.About(null, null, null, null, null, asList("Linux", "Mac OS X")), null, new File(pluginJarFileName), true);
when(registry.getPluginByIdOrFileName(pluginID, pluginJarFileName)).thenReturn(oldPluginDescriptor);
when(systemEnvironment.getOperatingSystemFamilyName()).thenReturn("Linux");
when(goPluginDescriptorBuilder.build(pluginJarFile, true)).thenReturn(newPluginDescriptor);
when(registry.unloadPlugin(newPluginDescriptor)).thenReturn(oldPluginDescriptor);
listener = new DefaultPluginJarChangeListener(registry, osgiManifestGenerator, osgiFramework, goPluginDescriptorBuilder, systemEnvironment);
listener.pluginJarUpdated(new PluginFileDetails(pluginJarFile, true));
verify(registry, times(1)).loadPlugin(newPluginDescriptor);
assertThat(newPluginDescriptor.getStatus().getMessages().size(), is(1));
assertThat(newPluginDescriptor.getStatus().getMessages().get(0),
is("Plugin with ID (some.id) is not valid: Incompatible with current operating system 'Linux'. Valid operating systems are: [Mac OS X]."));
}
@Test
public void shouldLoadAPluginWhenCurrentOSIsAmongTheListOfTargetOSesAsDeclaredByThePluginInItsXML() throws Exception {
String pluginJarFileName = "descriptor-aware-test-plugin.jar";
File pluginJarFile = new File(PLUGIN_DIR, pluginJarFileName);
copyPluginToTheDirectory(PLUGIN_DIR, pluginJarFileName);
GoPluginDescriptor descriptor = new GoPluginDescriptor("some.old.id", "1.0", new GoPluginDescriptor.About(null, null, null, null, null, asList("Windows", "Linux")), null,
new File(pluginJarFileName), false);
when(systemEnvironment.getOperatingSystemFamilyName()).thenReturn("Windows");
when(goPluginDescriptorBuilder.build(pluginJarFile, true)).thenReturn(descriptor);
listener = new DefaultPluginJarChangeListener(registry, osgiManifestGenerator, osgiFramework, goPluginDescriptorBuilder, systemEnvironment);
listener.pluginJarAdded(new PluginFileDetails(pluginJarFile, true));
verify(registry, times(1)).loadPlugin(descriptor);
verify(osgiFramework, times(1)).loadPlugin(descriptor);
}
@Test
public void shouldLoadAPluginWhenAListOfTargetOSesIsNotDeclaredByThePluginInItsXML() throws Exception {
String pluginJarFileName = "descriptor-aware-test-plugin.jar";
File pluginJarFile = new File(PLUGIN_DIR, pluginJarFileName);
copyPluginToTheDirectory(PLUGIN_DIR, pluginJarFileName);
GoPluginDescriptor descriptor = new GoPluginDescriptor("some.old.id", "1.0", new GoPluginDescriptor.About(null, null, null, null, null, null), null, new File(pluginJarFileName), false);
when(systemEnvironment.getOperatingSystemFamilyName()).thenReturn("Windows");
when(goPluginDescriptorBuilder.build(pluginJarFile, true)).thenReturn(descriptor);
listener = new DefaultPluginJarChangeListener(registry, osgiManifestGenerator, osgiFramework, goPluginDescriptorBuilder, systemEnvironment);
listener.pluginJarAdded(new PluginFileDetails(pluginJarFile, true));
verify(registry, times(1)).loadPlugin(descriptor);
verify(osgiFramework, times(1)).loadPlugin(descriptor);
}
@Test
public void shouldLoadAPluginAndProvidePluginDescriptorIfThePluginImplementsDescriptorAware() throws Exception {
String pluginJarFileName = "descriptor-aware-test-plugin.jar";
File pluginJarFile = new File(PLUGIN_DIR, pluginJarFileName);
copyPluginToTheDirectory(PLUGIN_DIR, pluginJarFileName);
GoPluginDescriptor descriptor = new GoPluginDescriptor("some.old.id", "1.0",
new GoPluginDescriptor.About(null, null, null, null, null, null), null, new File(pluginJarFileName), false);
when(systemEnvironment.getOperatingSystemFamilyName()).thenReturn("Windows");
when(goPluginDescriptorBuilder.build(pluginJarFile, true)).thenReturn(descriptor);
when(osgiFramework.hasReferenceFor(PluginDescriptorAware.class,descriptor.id())).thenReturn(true);
doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
return null;
}
}).when(osgiFramework).doOnAllWithExceptionHandlingForPlugin(
eq(PluginDescriptorAware.class), eq(descriptor.id()), Matchers.<Action<PluginDescriptorAware>>anyObject(),
Matchers.<ExceptionHandler<PluginDescriptorAware>>anyObject());
listener = new DefaultPluginJarChangeListener(registry, osgiManifestGenerator, osgiFramework, goPluginDescriptorBuilder, systemEnvironment);
listener.pluginJarAdded(new PluginFileDetails(pluginJarFile, true));
verify(registry, times(1)).loadPlugin(descriptor);
verify(osgiFramework, times(1)).loadPlugin(descriptor);
verify(osgiFramework, times(1)).hasReferenceFor(PluginDescriptorAware.class, descriptor.id());
verify(osgiFramework, times(1)).doOnAllWithExceptionHandlingForPlugin(eq(PluginDescriptorAware.class),
eq(descriptor.id()), Matchers.<Action<PluginDescriptorAware>>anyObject()
,Matchers.<ExceptionHandler<PluginDescriptorAware>>anyObject());
}
@Test
public void shouldNotProvidePluginDescriptorIfThePluginIsInvalidatedDuringLoad() throws Exception {
String pluginJarFileName = "descriptor-aware-test-plugin.jar";
File pluginJarFile = new File(PLUGIN_DIR, pluginJarFileName);
copyPluginToTheDirectory(PLUGIN_DIR, pluginJarFileName);
final GoPluginDescriptor descriptor = new GoPluginDescriptor("some.old.id", "1.0",
new GoPluginDescriptor.About(null, null, null, null, null, null), null, new File(pluginJarFileName), false);
when(systemEnvironment.getOperatingSystemFamilyName()).thenReturn("Windows");
when(goPluginDescriptorBuilder.build(pluginJarFile, true)).thenReturn(descriptor);
when(osgiFramework.hasReferenceFor(PluginDescriptorAware.class,descriptor.id())).thenReturn(true);
doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
descriptor.markAsInvalid(Arrays.asList("Marking invalid for test"),new Exception("dummy test exception"));
return null;
}
}).when(osgiFramework).loadPlugin(descriptor);
listener = new DefaultPluginJarChangeListener(registry, osgiManifestGenerator, osgiFramework, goPluginDescriptorBuilder, systemEnvironment);
listener.pluginJarAdded(new PluginFileDetails(pluginJarFile, true));
verify(registry, times(1)).loadPlugin(descriptor);
verify(osgiFramework, times(1)).loadPlugin(descriptor);
verify(osgiFramework, never()).hasReferenceFor(PluginDescriptorAware.class,descriptor.id());
verify(osgiFramework, never()).doOnAllForPlugin(eq(PluginDescriptorAware.class), eq(descriptor.id()), Matchers.<Action<PluginDescriptorAware>>anyObject());
}
@Test
public void shouldNotThrowExceptionIfThePluginImplementsDescriptorAwareIsNotAvailable() throws Exception {
String pluginJarFileName = "descriptor-aware-test-plugin.jar";
File pluginJarFile = new File(PLUGIN_DIR, pluginJarFileName);
copyPluginToTheDirectory(PLUGIN_DIR, pluginJarFileName);
GoPluginDescriptor descriptor = new GoPluginDescriptor("some.old.id", "1.0",
new GoPluginDescriptor.About(null, null, null, null, null, null), null, new File(pluginJarFileName), false);
when(systemEnvironment.getOperatingSystemFamilyName()).thenReturn("Windows");
when(goPluginDescriptorBuilder.build(pluginJarFile, true)).thenReturn(descriptor);
when(osgiFramework.hasReferenceFor(PluginDescriptorAware.class,descriptor.id())).thenReturn(false);
doThrow(new GoPluginFrameworkException("Failed to find service reference")).when(osgiFramework).
doOnAllForPlugin(eq(PluginDescriptorAware.class), eq(descriptor.id()), Matchers.<Action<PluginDescriptorAware>>anyObject());
listener = new DefaultPluginJarChangeListener(registry, osgiManifestGenerator, osgiFramework, goPluginDescriptorBuilder, systemEnvironment);
listener.pluginJarAdded(new PluginFileDetails(pluginJarFile, true));
verify(registry, times(1)).loadPlugin(descriptor);
verify(osgiFramework, times(1)).loadPlugin(descriptor);
verify(osgiFramework, times(1)).hasReferenceFor(PluginDescriptorAware.class,descriptor.id());
verify(osgiFramework, never()).doOnAllForPlugin(eq(PluginDescriptorAware.class), eq(descriptor.id()), Matchers.<Action<PluginDescriptorAware>>anyObject());
}
@Test
public void pluginDescriptorAwareCallbackErrorShouldNotBeFatal() throws Exception {
String pluginJarFileName = "descriptor-aware-test-plugin.jar";
File pluginJarFile = new File(PLUGIN_DIR, pluginJarFileName);
copyPluginToTheDirectory(PLUGIN_DIR, pluginJarFileName);
GoPluginDescriptor descriptor = new GoPluginDescriptor("some.old.id", "1.0",
new GoPluginDescriptor.About(null, null, null, null, null, null), null, new File(pluginJarFileName), false);
when(systemEnvironment.getOperatingSystemFamilyName()).thenReturn("Windows");
when(goPluginDescriptorBuilder.build(pluginJarFile, true)).thenReturn(descriptor);
when(osgiFramework.hasReferenceFor(PluginDescriptorAware.class,descriptor.id())).thenReturn(true);
doThrow(new RuntimeException("Exception in plugin descriptor")).when(osgiFramework).doOnAllForPlugin(eq(PluginDescriptorAware.class), eq(descriptor.id()),
Matchers.<Action<PluginDescriptorAware>>anyObject());
listener = new DefaultPluginJarChangeListener(registry, osgiManifestGenerator, osgiFramework, goPluginDescriptorBuilder, systemEnvironment);
listener.pluginJarAdded(new PluginFileDetails(pluginJarFile, true));
verify(registry, times(1)).loadPlugin(descriptor);
verify(osgiFramework, times(1)).loadPlugin(descriptor);
verify(osgiFramework, times(1)).hasReferenceFor(PluginDescriptorAware.class,descriptor.id());
verify(osgiFramework, times(1)).doOnAllWithExceptionHandlingForPlugin(eq(PluginDescriptorAware.class), eq(descriptor.id()), Matchers.<Action<PluginDescriptorAware>>anyObject(),
Matchers.<ExceptionHandler<PluginDescriptorAware>>anyObject());
}
private void copyPluginToTheDirectory(File destinationDir, String destinationFilenameOfPlugin) throws IOException, URISyntaxException {
FileUtils.copyFile(pathOfFileInDefaultFiles("descriptor-aware-test-plugin.jar"), new File(destinationDir, destinationFilenameOfPlugin));
}
private File pathOfFileInDefaultFiles(String filePath) {
return new File(getClass().getClassLoader().getResource("defaultFiles/" + filePath).getFile());
}
}