private void assertActiveBundle(String symbolicName) { for (Bundle bundle : bundleContext.getBundles()) { if (bundle.getSymbolicName().equals( symbolicName )) { Assert.assertEquals( symbolicName + " was found, but not in an ACTIVE state.", Bundle.ACTIVE, bundle.getState()); return; } } Assert.fail("Could not find bundle: " + symbolicName); } }
@Test public void shouldNotFailToRegisterOtherClassesIfAClassCannotBeLoadedBecauseOfWrongPath() throws Exception { File bundleWithActivator = createBundleWithActivator(BUNDLE_DIR_WHICH_HAS_PROPER_ACTIVATOR, DummyTestPlugin.class); File sourceClassFile = new File(bundleWithActivator, "com/thoughtworks/go/plugin/activation/test/DummyTestPlugin.class"); File destinationFile = new File(bundleWithActivator, "ABC-DEF/com/thoughtworks/go/plugin/activation/test/"); FileUtils.copyFileToDirectory(sourceClassFile, destinationFile, true); Bundle bundle = installBundleFoundInDirectory(bundleWithActivator); assertThat(bundle.getState(), is(Bundle.UNINSTALLED)); }
@Test public void shouldLoadAValidPluginWithMultipleExtensions_ImplementingDifferentExtensions() throws Exception { Bundle bundle = pluginOSGiFramework.loadPlugin(new GoPluginDescriptor(null, null, null, null, validMultipleExtensionPluginBundleDir, true)); assertThat(bundle.getState(), is(Bundle.ACTIVE)); BundleContext context = bundle.getBundleContext(); String taskExtensionFilter = String.format("(&(%s=%s)(%s=%s))", Constants.BUNDLE_SYMBOLICNAME, "valid-plugin-with-multiple-extensions", Constants.BUNDLE_CATEGORY, "task"); String analyticsExtensionFilter = String.format("(&(%s=%s)(%s=%s))", Constants.BUNDLE_SYMBOLICNAME, "valid-plugin-with-multiple-extensions", Constants.BUNDLE_CATEGORY, "analytics"); ServiceReference<?>[] taskExtensionServiceReferences = context.getServiceReferences(GoPlugin.class.getCanonicalName(), taskExtensionFilter); assertThat(taskExtensionServiceReferences.length, is(1)); assertThat(((GoPlugin) context.getService(taskExtensionServiceReferences[0])).pluginIdentifier().getExtension(), is("task")); ServiceReference<?>[] analyticsExtensionServiceReferences = context.getServiceReferences(GoPlugin.class.getCanonicalName(), analyticsExtensionFilter); assertThat(analyticsExtensionServiceReferences.length, is(1)); assertThat(((GoPlugin) context.getService(analyticsExtensionServiceReferences[0])).pluginIdentifier().getExtension(), is("analytics")); }
@Test public void shouldUseOldClassLoaderBehaviourWhenSystemPropertyIsSet() { systemEnvironment.setProperty("gocd.plugins.classloader.old", "true"); final GoPluginDescriptor descriptor = new GoPluginDescriptor("plugin.to.test.classloader", null, null, null, pluginToTestClassloadePluginBundleDir, true); Bundle bundle = pluginOSGiFramework.loadPlugin(descriptor); registry.loadPlugin(descriptor); assertThat(bundle.getState(), is(Bundle.ACTIVE)); ActionWithReturn<GoPlugin, Object> action = (plugin, pluginDescriptor) -> { assertThat(pluginDescriptor, is(descriptor)); assertThat(Thread.currentThread().getContextClassLoader().getClass().getCanonicalName(), not(BundleClassLoader.class.getCanonicalName())); return null; }; pluginOSGiFramework.doOn(GoPlugin.class, "plugin.to.test.classloader", "notification", action); }
@Test public void shouldNotRegisterAsAnOSGiServiceAClassImplementingGoPluginWithOnlyAOneArgConstructor() throws Exception { Bundle bundle = installBundleWithClasses(DummyGoPluginWithOneArgConstructorOnly.class); assertThat(bundle.getState(),is(Bundle.UNINSTALLED)); GoPluginDescriptor descriptor = registry.getPlugin(GO_TEST_DUMMY_SYMBOLIC_NAME); assertThat(descriptor.isInvalid(), is(true)); String error = descriptor.getStatus().getMessages().get(0); assertThat(error.contains("DummyGoPluginWithOneArgConstructorOnly"),is(true)); assertThat(error.contains("Make sure it and all of its parent classes have a default constructor."),is(true)); }
@Test public void shouldNotRegisterAsAnOSGiServiceAClassWhichThrowsExceptionDuringInstantiation() throws Exception { Bundle bundle = installBundleWithClasses(DummyTestPlugin.class, DummyGoPluginWhichThrowsAnExceptionDuringConstruction.class); assertThat(bundle.getState(),is(Bundle.UNINSTALLED)); GoPluginDescriptor descriptor = registry.getPlugin(GO_TEST_DUMMY_SYMBOLIC_NAME); assertThat(descriptor.isInvalid(), is(true)); String error = descriptor.getStatus().getMessages().get(0); assertThat(error.contains("DummyGoPluginWhichThrowsAnExceptionDuringConstruction"), is(true)); assertThat(error.contains("java.lang.RuntimeException: Ouch! I failed!"), is(true)); }
@Test public void shouldUnloadALoadedPlugin() throws Exception { GoPluginDescriptor pluginDescriptor = new GoPluginDescriptor(null, null, null, null, descriptorBundleDir, true); Bundle bundle = pluginOSGiFramework.loadPlugin(pluginDescriptor); BundleContext context = bundle.getBundleContext(); ServiceReference<?>[] allServiceReferences = context.getServiceReferences(GoPlugin.class.getCanonicalName(), null); assertThat(allServiceReferences.length, is(1)); GoPlugin service = (GoPlugin) context.getService(allServiceReferences[0]); assertThat("@Load should have been called", getIntField(service, "loadCalled"), is(1)); pluginDescriptor.setBundle(bundle); pluginOSGiFramework.unloadPlugin(pluginDescriptor); assertThat(bundle.getState(), is(Bundle.UNINSTALLED)); assertThat("@UnLoad should have been called", getIntField(service, "unloadCalled"), is(1)); }
@Test public void shouldNotLoadClassesFoundInMETA_INFEvenIfTheyAreProperGoExtensionPoints() throws Exception { File bundleWithActivator = createBundleWithActivator(BUNDLE_DIR_WHICH_HAS_PROPER_ACTIVATOR, DummyTestPlugin.class); File sourceClassFile = new File(bundleWithActivator, "com/thoughtworks/go/plugin/activation/test/DummyTestPlugin.class"); File destinationFile = new File(bundleWithActivator, "META-INF/com/thoughtworks/go/plugin/activation/test/"); FileUtils.moveFileToDirectory(sourceClassFile, destinationFile, true); Bundle bundle = installBundleFoundInDirectory(bundleWithActivator); assertThat(bundle.getState(), is(Bundle.UNINSTALLED)); GoPluginDescriptor descriptor = registry.getPlugin(GO_TEST_DUMMY_SYMBOLIC_NAME); assertThat(descriptor.isInvalid(), is(true)); assertThat(descriptor.getStatus().getMessages().contains(NO_EXT_ERR_MSG),is(true)); }
@Test public void shouldNotRegisterAnAnonymousClassThatImplementsAnExtensionPoint() throws IOException { Bundle bundle = installBundleWithClasses(DummyClassProvidingAnonymousClass.getAnonymousClass().getClass()); assertThat(bundle.getState(), is(Bundle.UNINSTALLED)); GoPluginDescriptor descriptor = registry.getPlugin(GO_TEST_DUMMY_SYMBOLIC_NAME); assertThat(descriptor.isInvalid(), is(true)); assertThat(descriptor.getStatus().getMessages().contains(NO_EXT_ERR_MSG),is(true)); }
@Test public void shouldNotRegisterAnAnonymousClassDefinedWithinAnInnerClassThatImplementsAnExtensionPoint() throws IOException { Bundle bundle = installBundleWithClasses(DummyClassProvidingAnonymousClass.DummyInnerClassProvidingAnonymousClass.getAnonymousClass().getClass()); assertThat(bundle.getState(), is(Bundle.UNINSTALLED)); GoPluginDescriptor descriptor = registry.getPlugin(GO_TEST_DUMMY_SYMBOLIC_NAME); assertThat(descriptor.isInvalid(), is(true)); assertThat(descriptor.getStatus().getMessages().contains(NO_EXT_ERR_MSG), is(true)); }
@Test public void shouldNotRegisterAsAnOSGiServiceAClassWhichIsNotPublic() throws Exception { Bundle bundle = installBundleWithClasses(DummyTestPluginWhichIsNotPublic.class); assertThat(bundle.getState(), is(Bundle.UNINSTALLED)); GoPluginDescriptor descriptor = registry.getPlugin(GO_TEST_DUMMY_SYMBOLIC_NAME); assertThat(descriptor.isInvalid(), is(true)); assertThat(descriptor.getStatus().getMessages().contains(NO_EXT_ERR_MSG), is(true)); }
@Test public void shouldNotRegisterLocalInnerClassesThatImplementAnExtensionPoint() throws IOException { Bundle bundle = installBundleWithClasses(DummyClassWithLocalInnerClass.class); assertThat(bundle.getState(), is(Bundle.UNINSTALLED)); GoPluginDescriptor descriptor = registry.getPlugin(GO_TEST_DUMMY_SYMBOLIC_NAME); assertThat(descriptor.isInvalid(), is(true)); assertThat(descriptor.getStatus().getMessages().contains(NO_EXT_ERR_MSG), is(true)); }
@Test public void shouldNotRegisterAsAnOSGiServiceAnExtensionClassWhichDoesNotImplementAGoExtensionPoint() throws Exception { Bundle bundle = installBundleWithClasses(NotAGoExtensionPoint.class, NotAGoExtensionAsItDoesNotImplementAnyExtensionPoints.class); assertThat(bundle.getState(), is(Bundle.UNINSTALLED)); GoPluginDescriptor descriptor = registry.getPlugin(GO_TEST_DUMMY_SYMBOLIC_NAME); assertThat(descriptor.isInvalid(), is(true)); assertThat(descriptor.getStatus().getMessages().contains(NO_EXT_ERR_MSG), is(true)); }
@Test public void shouldNotLoadAClassFoundInLibDirectoryEvenIfItIsAProperGoExtensionPoints() throws Exception { Bundle bundle = installBundleWithClasses(DummyTestPluginInLibDirectory.class); assertThat(bundle.getState(), is(Bundle.UNINSTALLED)); GoPluginDescriptor descriptor = registry.getPlugin(GO_TEST_DUMMY_SYMBOLIC_NAME); assertThat(descriptor.isInvalid(), is(true)); assertThat(descriptor.getStatus().getMessages().contains(NO_EXT_ERR_MSG), is(true)); }
@Test public void shouldNotRegisterAsAnOSGiServiceAClassImplementingGoPluginWithoutAPublicConstructor() throws Exception { Bundle bundle = installBundleWithClasses(DummyTestPluginWithNonPublicDefaultConstructor.class); assertThat(bundle.getState(), is(Bundle.UNINSTALLED)); GoPluginDescriptor descriptor = registry.getPlugin(GO_TEST_DUMMY_SYMBOLIC_NAME); assertThat(descriptor.isInvalid(), is(true)); assertThat(descriptor.getStatus().getMessages().contains(NO_EXT_ERR_MSG), is(true)); }
@Test public void shouldNotRegisterAsAnOSGiServiceAClassWhichIsAbstract() throws Exception { Bundle bundle = installBundleWithClasses(AbstractTestPlugin.class); assertThat(bundle.getState(), is(Bundle.UNINSTALLED)); GoPluginDescriptor descriptor = registry.getPlugin(GO_TEST_DUMMY_SYMBOLIC_NAME); assertThat(descriptor.isInvalid(), is(true)); assertThat(descriptor.getStatus().getMessages().contains(NO_EXT_ERR_MSG), is(true)); }
@Test public void shouldNotRegisterAsAnOSGiServiceAnInterfaceEvenIfItImplementsAGoExtensionPointInterface() throws Exception { Bundle bundle = installBundleWithClasses(TestGoPluginExtensionInterface.class); assertThat(bundle.getState(), is(Bundle.UNINSTALLED)); GoPluginDescriptor descriptor = registry.getPlugin(GO_TEST_DUMMY_SYMBOLIC_NAME); assertThat(descriptor.isInvalid(), is(true)); assertThat(descriptor.getStatus().getMessages().contains(NO_EXT_ERR_MSG), is(true)); }
@Test public void shouldNotRegisterPublicInnerClassesThatImplementAnExtensionPointInsidePackageLevelClass() throws IOException { Bundle bundle = installBundleWithClasses(PackageLevelClassWithPublicInnerClass.class, PackageLevelClassWithPublicInnerClass.DummyInnerClassWithExtension.class); assertThat(bundle.getState(), is(Bundle.UNINSTALLED)); GoPluginDescriptor descriptor = registry.getPlugin(GO_TEST_DUMMY_SYMBOLIC_NAME); assertThat(descriptor.isInvalid(), is(true)); assertThat(descriptor.getStatus().getMessages().contains(NO_EXT_ERR_MSG), is(true)); }
@Test public void shouldMarkAPluginInvalidAnUnloadPluginIfAtLoadOfAnyExtensionPointInItFails() throws Exception { String id = "com.tw.go.exception.throwing.at.loadplugin"; GoPluginDescriptor pluginDescriptor = new GoPluginDescriptor(id, null, null, null, exceptionThrowingAtLoadDescriptorBundleDir, true); registry.loadPlugin(pluginDescriptor); assertThat(pluginDescriptor.isInvalid(), is(false)); Bundle bundle = pluginOSGiFramework.loadPlugin(pluginDescriptor); assertThat(pluginDescriptor.isInvalid(),is(true)); assertThat(bundle.getState(),is(Bundle.UNINSTALLED)); }