From 6813418034cc8a46124b326d30ec130d81aff415 Mon Sep 17 00:00:00 2001 From: Maros Marsalek Date: Wed, 23 Jul 2014 13:45:57 +0200 Subject: [PATCH] Bug-1520 Config subsystem:config-impl tests Change-Id: I8c09cbf90585e179f84e3ac1e83e5946379be66f Signed-off-by: Maros Marsalek --- .../osgi/BlankTransactionServiceTracker.java | 39 +++- .../impl/osgi/ModuleFactoryBundleTracker.java | 16 +- .../manager/impl/util/InterfacesHelper.java | 1 - .../manager/impl/util/ModuleQNameUtil.java | 5 +- .../impl/util/OsgiRegistrationUtil.java | 11 +- .../BlankTransactionServiceTrackerTest.java | 83 ++++++++ ...textBackedModuleFactoriesResolverTest.java | 104 ++++++++++ .../osgi/ExtensibleBundleTrackerTest.java | 76 +++++++ .../osgi/ModuleFactoryBundleTrackerTest.java | 193 ++++++++++++++++++ .../impl/util/InterfacesHelperTest.java | 29 ++- .../impl/util/OsgiRegistrationUtilTest.java | 61 ++++++ ...ctTestingFixedThreadPoolModuleFactory.java | 2 +- .../test/SimpleConfigurationTest.java | 3 +- .../module-factories/module-factory-fail | 1 + .../module-factories/module-factory-ok | 1 + 15 files changed, 595 insertions(+), 30 deletions(-) create mode 100644 opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/osgi/BlankTransactionServiceTrackerTest.java create mode 100644 opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/osgi/BundleContextBackedModuleFactoriesResolverTest.java create mode 100644 opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/osgi/ExtensibleBundleTrackerTest.java create mode 100644 opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/osgi/ModuleFactoryBundleTrackerTest.java create mode 100644 opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/util/OsgiRegistrationUtilTest.java create mode 100644 opendaylight/config/config-manager/src/test/resources/module-factories/module-factory-fail create mode 100644 opendaylight/config/config-manager/src/test/resources/module-factories/module-factory-ok diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/BlankTransactionServiceTracker.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/BlankTransactionServiceTracker.java index 720b7197ea..375ef59487 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/BlankTransactionServiceTracker.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/BlankTransactionServiceTracker.java @@ -7,6 +7,8 @@ */ package org.opendaylight.controller.config.manager.impl.osgi; +import com.google.common.annotations.VisibleForTesting; +import javax.management.ObjectName; import org.opendaylight.controller.config.api.ConflictingVersionException; import org.opendaylight.controller.config.api.ValidationException; import org.opendaylight.controller.config.api.jmx.CommitStatus; @@ -17,8 +19,6 @@ import org.osgi.util.tracker.ServiceTrackerCustomizer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.management.ObjectName; - /** * Every time factory is added or removed, blank transaction is triggered to handle * {@link org.opendaylight.controller.config.spi.ModuleFactory#getDefaultModules(org.opendaylight.controller.config.api.DependencyResolverFactory, org.osgi.framework.BundleContext)} @@ -27,10 +27,29 @@ import javax.management.ObjectName; public class BlankTransactionServiceTracker implements ServiceTrackerCustomizer { private static final Logger logger = LoggerFactory.getLogger(BlankTransactionServiceTracker.class); - private final ConfigRegistryImpl configRegistry; + public static final int DEFAULT_MAX_ATTEMPTS = 10; - public BlankTransactionServiceTracker(ConfigRegistryImpl configRegistry) { - this.configRegistry = configRegistry; + private final BlankTransaction blankTransaction; + private int maxAttempts; + + public BlankTransactionServiceTracker(final ConfigRegistryImpl configRegistry) { + this(new BlankTransaction() { + @Override + public CommitStatus hit() throws ValidationException, ConflictingVersionException { + ObjectName tx = configRegistry.beginConfig(true); + return configRegistry.commitConfig(tx); + } + }); + } + + public BlankTransactionServiceTracker(final BlankTransaction blankTransaction) { + this(blankTransaction, DEFAULT_MAX_ATTEMPTS); + } + + @VisibleForTesting + BlankTransactionServiceTracker(final BlankTransaction blankTx, final int maxAttempts) { + this.blankTransaction = blankTx; + this.maxAttempts = maxAttempts; } @Override @@ -42,13 +61,10 @@ public class BlankTransactionServiceTracker implements ServiceTrackerCustomizer< synchronized void blankTransaction() { // race condition check: config-persister might push new configuration while server is starting up. ConflictingVersionException lastException = null; - int maxAttempts = 10; for (int i = 0; i < maxAttempts; i++) { try { // create transaction - boolean blankTransaction = true; - ObjectName tx = configRegistry.beginConfig(blankTransaction); - CommitStatus commitStatus = configRegistry.commitConfig(tx); + CommitStatus commitStatus = blankTransaction.hit(); logger.debug("Committed blank transaction with status {}", commitStatus); return; } catch (ConflictingVersionException e) { @@ -77,4 +93,9 @@ public class BlankTransactionServiceTracker implements ServiceTrackerCustomizer< public void removedService(ServiceReference moduleFactoryServiceReference, Object o) { blankTransaction(); } + + @VisibleForTesting + static interface BlankTransaction { + CommitStatus hit() throws ValidationException, ConflictingVersionException; + } } diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ModuleFactoryBundleTracker.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ModuleFactoryBundleTracker.java index 05ca43c3e2..3015ed229e 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ModuleFactoryBundleTracker.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/osgi/ModuleFactoryBundleTracker.java @@ -9,6 +9,7 @@ package org.opendaylight.controller.config.manager.impl.osgi; import static java.lang.String.format; +import com.google.common.annotations.VisibleForTesting; import java.io.InputStream; import java.net.URL; import java.util.List; @@ -70,9 +71,10 @@ public class ModuleFactoryBundleTracker implements BundleTrackerCustomizer registerFactory(String factoryClassName, Bundle bundle) { + @VisibleForTesting + protected static ServiceRegistration registerFactory(String factoryClassName, Bundle bundle) { String errorMessage; + Exception ex = null; try { Class clazz = bundle.loadClass(factoryClassName); if (ModuleFactory.class.isAssignableFrom(clazz)) { @@ -86,10 +88,12 @@ public class ModuleFactoryBundleTracker implements BundleTrackerCustomizer> getOsgiRegistrationTypes( Class configBeanClass) { - // TODO test with service interface hierarchy Set> serviceInterfaces = getServiceInterfaces(configBeanClass); Set> result = new HashSet<>(); for (Class clazz : serviceInterfaces) { diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/util/ModuleQNameUtil.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/util/ModuleQNameUtil.java index e84337756e..f1072a76ae 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/util/ModuleQNameUtil.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/util/ModuleQNameUtil.java @@ -9,6 +9,7 @@ package org.opendaylight.controller.config.manager.impl.util; import org.opendaylight.controller.config.spi.ModuleFactory; import org.opendaylight.yangtools.yang.binding.annotations.ModuleQName; +import org.opendaylight.yangtools.yang.common.QName; import org.osgi.framework.BundleContext; import java.util.HashSet; @@ -31,9 +32,7 @@ public class ModuleQNameUtil { inspected = inspected.getSuperclass(); } if (annotation != null) { - // FIXME - String qName = "(" + annotation.namespace() + "?revision=" + annotation.revision() + ")" + annotation.name(); - result.add(qName); + result.add(QName.create(annotation.namespace(), annotation.revision(), annotation.name()).toString()); } } return result; diff --git a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/util/OsgiRegistrationUtil.java b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/util/OsgiRegistrationUtil.java index 8873596642..2df28f0a15 100644 --- a/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/util/OsgiRegistrationUtil.java +++ b/opendaylight/config/config-manager/src/main/java/org/opendaylight/controller/config/manager/impl/util/OsgiRegistrationUtil.java @@ -8,6 +8,11 @@ package org.opendaylight.controller.config.manager.impl.util; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.ListIterator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; import org.osgi.util.tracker.BundleTracker; @@ -15,12 +20,6 @@ import org.osgi.util.tracker.ServiceTracker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.ArrayList; -import java.util.List; -import java.util.ListIterator; - -import static com.google.common.base.Preconditions.checkNotNull; - public class OsgiRegistrationUtil { private static final Logger logger = LoggerFactory.getLogger(OsgiRegistrationUtil.class); diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/osgi/BlankTransactionServiceTrackerTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/osgi/BlankTransactionServiceTrackerTest.java new file mode 100644 index 0000000000..471c98a676 --- /dev/null +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/osgi/BlankTransactionServiceTrackerTest.java @@ -0,0 +1,83 @@ +package org.opendaylight.controller.config.manager.impl.osgi; + +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.assertSame; +import static junit.framework.Assert.fail; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import java.util.Collections; +import javax.management.ObjectName; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.opendaylight.controller.config.api.ConflictingVersionException; +import org.opendaylight.controller.config.api.ModuleIdentifier; +import org.opendaylight.controller.config.api.ValidationException; +import org.opendaylight.controller.config.api.jmx.CommitStatus; +import org.opendaylight.controller.config.spi.ModuleFactory; +import org.osgi.framework.ServiceReference; + +public class BlankTransactionServiceTrackerTest { + + @Mock + private BlankTransactionServiceTracker.BlankTransaction blankTx; + private BlankTransactionServiceTracker tracker; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + doReturn(new CommitStatus(Collections.emptyList(), Collections.emptyList(), Collections.emptyList())).when(blankTx).hit(); + tracker = new BlankTransactionServiceTracker(blankTx); + } + + @Test + public void testBlankTransaction() throws Exception { + tracker.addingService(getMockServiceReference()); + tracker.modifiedService(getMockServiceReference(), null); + tracker.removedService(getMockServiceReference(), null); + verify(blankTx, times(3)).hit(); + } + + @Test + public void testValidationException() throws Exception { + IllegalArgumentException argumentException = new IllegalArgumentException(); + ValidationException validationException = ValidationException.createForSingleException(new ModuleIdentifier("m", "i"), argumentException); + doThrow(validationException).when(blankTx).hit(); + try { + tracker.addingService(getMockServiceReference()); + } catch (Exception e) { + verify(blankTx, times(1)).hit(); + assertNotNull(e.getCause()); + assertSame(validationException, e.getCause()); + return; + } + + fail("Exception should have occurred for validation exception"); + } + + @Test + public void testConflictingException() throws Exception { + int maxAttempts = 2; + tracker = new BlankTransactionServiceTracker(blankTx, maxAttempts); + + final ConflictingVersionException ex = new ConflictingVersionException(); + doThrow(ex).when(blankTx).hit(); + try { + tracker.addingService(getMockServiceReference()); + } catch (Exception e) { + verify(blankTx, times(maxAttempts)).hit(); + return; + } + + fail("Exception should have occurred for conflicting exception"); + } + + private ServiceReference getMockServiceReference() { + return mock(ServiceReference.class); + } +} diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/osgi/BundleContextBackedModuleFactoriesResolverTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/osgi/BundleContextBackedModuleFactoriesResolverTest.java new file mode 100644 index 0000000000..dc3deddddc --- /dev/null +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/osgi/BundleContextBackedModuleFactoriesResolverTest.java @@ -0,0 +1,104 @@ +package org.opendaylight.controller.config.manager.impl.osgi; + +import static junit.framework.Assert.fail; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.matchers.JUnitMatchers.containsString; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; + +import com.google.common.collect.Lists; +import java.util.Map; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.opendaylight.controller.config.spi.ModuleFactory; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; + +public class BundleContextBackedModuleFactoriesResolverTest { + + @Mock + private BundleContext bundleContext; + private BundleContextBackedModuleFactoriesResolver resolver; + private ServiceReference s1; + private ServiceReference s2; + private ModuleFactory f1; + private ModuleFactory f2; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + s1 = getServiceRef(); + s2 = getServiceRef(); + doReturn(Lists.newArrayList(s1, s2)).when(bundleContext).getServiceReferences(ModuleFactory.class, null); + f1 = getMockFactory("f1"); + doReturn(f1).when(bundleContext).getService(s1); + f2 = getMockFactory("f2"); + doReturn(f2).when(bundleContext).getService(s2); + resolver = new BundleContextBackedModuleFactoriesResolver(bundleContext); + } + + private ModuleFactory getMockFactory(String name) { + ModuleFactory mock = mock(ModuleFactory.class); + doReturn(name).when(mock).toString(); + doReturn(name).when(mock).getImplementationName(); + return mock; + } + + private ServiceReference getServiceRef() { + ServiceReference mock = mock(ServiceReference.class); + doReturn("serviceRef").when(mock).toString(); + final Bundle bundle = mock(Bundle.class); + doReturn(bundleContext).when(bundle).getBundleContext(); + doReturn(bundle).when(mock).getBundle(); + return mock; + } + + @Test + public void testGetAllFactories() throws Exception { + Map> allFactories = resolver.getAllFactories(); + assertEquals(2, allFactories.size()); + assertTrue(allFactories.containsKey(f1.getImplementationName())); + assertEquals(f1, allFactories.get(f1.getImplementationName()).getKey()); + assertEquals(bundleContext, allFactories.get(f1.getImplementationName()).getValue()); + assertTrue(allFactories.containsKey(f2.getImplementationName())); + assertEquals(f2, allFactories.get(f2.getImplementationName()).getKey()); + assertEquals(bundleContext, allFactories.get(f2.getImplementationName()).getValue()); + } + + @Test + public void testDuplicateFactories() throws Exception { + doReturn(f1).when(bundleContext).getService(s2); + try { + resolver.getAllFactories(); + } catch (Exception e) { + assertThat(e.getMessage(), containsString(f1.getImplementationName())); + assertThat(e.getMessage(), containsString("unique")); + return; + } + + fail("Should fail with duplicate factory name"); + } + + @Test(expected = NullPointerException.class) + public void testNullFactory() throws Exception { + doReturn(null).when(bundleContext).getService(s2); + resolver.getAllFactories(); + } + + @Test(expected = IllegalStateException.class) + public void testNullFactoryName() throws Exception { + doReturn(null).when(f1).getImplementationName(); + resolver.getAllFactories(); + } + + @Test(expected = NullPointerException.class) + public void testNullBundleName() throws Exception { + doReturn(null).when(s1).getBundle(); + resolver.getAllFactories(); + } +} diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/osgi/ExtensibleBundleTrackerTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/osgi/ExtensibleBundleTrackerTest.java new file mode 100644 index 0000000000..9a3ba64419 --- /dev/null +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/osgi/ExtensibleBundleTrackerTest.java @@ -0,0 +1,76 @@ +package org.opendaylight.controller.config.manager.impl.osgi; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.verifyZeroInteractions; + +import com.google.common.util.concurrent.Futures; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InOrder; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleEvent; +import org.osgi.util.tracker.BundleTrackerCustomizer; + +public class ExtensibleBundleTrackerTest { + + @Mock + private BundleContext bundleContext; + @Mock + private Bundle bundle; + @Mock + private BundleEvent bundleEvent; + + @Mock + private BundleTrackerCustomizer primaryTracker; + @Mock + private BundleTrackerCustomizer additionalTracker; + + private ExtensibleBundleTracker extensibleBundleTracker; + private Object primaryValue = new Object(); + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + doReturn("bundle").when(bundle).toString(); + doReturn("bundleEvent").when(bundleEvent).toString(); + + doReturn(primaryValue).when(primaryTracker).addingBundle(bundle, bundleEvent); + doNothing().when(primaryTracker).modifiedBundle(bundle, bundleEvent, primaryValue); + doNothing().when(primaryTracker).removedBundle(bundle, bundleEvent, primaryValue); + + doReturn(new Object()).when(additionalTracker).addingBundle(bundle, bundleEvent); + doNothing().when(additionalTracker).modifiedBundle(bundle, bundleEvent, null); + doNothing().when(additionalTracker).removedBundle(bundle, bundleEvent, null); + extensibleBundleTracker = new ExtensibleBundleTracker<>(bundleContext, primaryTracker, additionalTracker); + } + + @Test + public void testAddingBundle() throws Exception { + assertEquals(primaryValue, extensibleBundleTracker.addingBundle(bundle, bundleEvent).get()); + InOrder inOrder = Mockito.inOrder(primaryTracker, additionalTracker); + inOrder.verify(primaryTracker).addingBundle(bundle, bundleEvent); + inOrder.verify(additionalTracker).addingBundle(bundle, bundleEvent); + } + + @Test + public void testRemovedBundle() throws Exception { + extensibleBundleTracker.removedBundle(bundle, bundleEvent, Futures.immediateFuture(primaryValue)); + InOrder inOrder = Mockito.inOrder(primaryTracker, additionalTracker); + inOrder.verify(primaryTracker).removedBundle(bundle, bundleEvent, primaryValue); + inOrder.verify(additionalTracker).removedBundle(bundle, bundleEvent, null); + } + + @Test + public void testRemovedBundleWithEx() throws Exception { + IllegalStateException throwable = new IllegalStateException(); + extensibleBundleTracker.removedBundle(bundle, bundleEvent, Futures.immediateFailedFuture(throwable)); + verifyZeroInteractions(primaryTracker); + verifyZeroInteractions(additionalTracker); + } +} diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/osgi/ModuleFactoryBundleTrackerTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/osgi/ModuleFactoryBundleTrackerTest.java new file mode 100644 index 0000000000..5b83412083 --- /dev/null +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/osgi/ModuleFactoryBundleTrackerTest.java @@ -0,0 +1,193 @@ +package org.opendaylight.controller.config.manager.impl.osgi; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyObject; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; + +import java.util.Dictionary; +import java.util.Set; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.opendaylight.controller.config.api.DependencyResolver; +import org.opendaylight.controller.config.api.DependencyResolverFactory; +import org.opendaylight.controller.config.api.DynamicMBeanWithInstance; +import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface; +import org.opendaylight.controller.config.spi.Module; +import org.opendaylight.controller.config.spi.ModuleFactory; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleEvent; +import org.osgi.framework.ServiceRegistration; + +public class ModuleFactoryBundleTrackerTest { + + @Mock + private Bundle bundle; + @Mock + private BundleContext context; + @Mock + private ServiceRegistration reg; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + doAnswer(new Answer() { + @Override + public Object answer(final InvocationOnMock invocation) throws Throwable { + return getClass().getClassLoader().loadClass((String) invocation.getArguments()[0]); + } + }).when(bundle).loadClass(anyString()); + doReturn("mockBundle").when(bundle).toString(); + doReturn(context).when(bundle).getBundleContext(); + doReturn(reg).when(context).registerService(anyString(), anyObject(), any(Dictionary.class)); + } + + @Test + public void testRegisterFactory() throws Exception { + ModuleFactoryBundleTracker.registerFactory(TestingFactory.class.getName(), bundle); + verify(context).registerService(ModuleFactory.class.getName(), TestingFactory.currentInstance, null); + } + + @Test + public void testRegisterFactoryInstantiateEx() throws Exception { + try { + ModuleFactoryBundleTracker.registerFactory(WrongConstructorTestingFactory.class.getName(), bundle); + } catch (Exception e) { + verifyZeroInteractions(context); + assertNotNull(e.getCause()); + assertEquals(InstantiationException.class, e.getCause().getClass()); + return; + } + + fail("Cannot register without proper constructor"); + } + + @Test + public void testRegisterFactoryInstantiateExAccess() throws Exception { + try { + ModuleFactoryBundleTracker.registerFactory(NoAccessConstructorTestingFactory.class.getName(), bundle); + } catch (Exception e) { + verifyZeroInteractions(context); + assertNotNull(e.getCause()); + assertEquals(IllegalAccessException.class, e.getCause().getClass()); + return; + } + + fail("Cannot register without proper constructor"); + } + + @Test + public void testRegisterFactoryNotExtending() throws Exception { + try { + ModuleFactoryBundleTracker.registerFactory(NotExtendingTestingFactory.class.getName(), bundle); + } catch (Exception e) { + verifyZeroInteractions(context); + return; + } + + fail("Cannot register without extend"); + } + + @Test + public void testRegisterFactoryNotExisting() throws Exception { + try { + ModuleFactoryBundleTracker.registerFactory("Unknown class", bundle); + } catch (Exception e) { + verifyZeroInteractions(context); + assertNotNull(e.getCause()); + assertEquals(ClassNotFoundException.class, e.getCause().getClass()); + return; + } + + fail("Cannot register without extend"); + } + + @Mock + private BlankTransactionServiceTracker blankTxTracker; + + @Test + public void testAddingBundle() throws Exception { + final ModuleFactoryBundleTracker tracker = new ModuleFactoryBundleTracker(blankTxTracker); + doReturn(getClass().getResource("/module-factories/module-factory-ok")).when(bundle).getEntry(anyString()); + tracker.addingBundle(bundle, mock(BundleEvent.class)); + verify(context).registerService(ModuleFactory.class.getName(), TestingFactory.currentInstance, null); + } + + @Test + public void testAddingBundleError() throws Exception { + final ModuleFactoryBundleTracker tracker = new ModuleFactoryBundleTracker(blankTxTracker); + doReturn(getClass().getResource("/module-factories/module-factory-fail")).when(bundle).getEntry(anyString()); + try { + tracker.addingBundle(bundle, mock(BundleEvent.class)); + } catch (Exception e) { + verifyZeroInteractions(context); + return; + } + + fail("Cannot register"); + } + + static class WrongConstructorTestingFactory extends TestingFactory { + WrongConstructorTestingFactory(String randomParam) { + } + } + + static class NotExtendingTestingFactory {} + + static class NoAccessConstructorTestingFactory extends TestingFactory { + private NoAccessConstructorTestingFactory() { + } + } + + static class TestingFactory implements ModuleFactory { + + static TestingFactory currentInstance; + + TestingFactory() { + currentInstance = this; + } + + @Override + public String getImplementationName() { + return "Testing"; + } + + @Override + public Module createModule(final String instanceName, final DependencyResolver dependencyResolver, final BundleContext bundleContext) { + throw new UnsupportedOperationException(); + } + + @Override + public Module createModule(final String instanceName, final DependencyResolver dependencyResolver, final DynamicMBeanWithInstance old, final BundleContext bundleContext) throws Exception { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isModuleImplementingServiceInterface(final Class serviceInterface) { + throw new UnsupportedOperationException(); + } + + @Override + public Set> getImplementedServiceIntefaces() { + throw new UnsupportedOperationException(); + } + + @Override + public Set getDefaultModules(final DependencyResolverFactory dependencyResolverFactory, final BundleContext bundleContext) { + throw new UnsupportedOperationException(); + } + } +} diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/util/InterfacesHelperTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/util/InterfacesHelperTest.java index 22ea528030..220bef03bc 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/util/InterfacesHelperTest.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/util/InterfacesHelperTest.java @@ -9,20 +9,19 @@ package org.opendaylight.controller.config.manager.impl.util; import static org.junit.Assert.assertEquals; +import com.google.common.collect.Sets; +import java.util.Collections; import java.util.HashSet; import java.util.Set; - import javax.management.MXBean; - import org.junit.Test; import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface; +import org.opendaylight.controller.config.api.annotations.ServiceInterfaceAnnotation; import org.opendaylight.controller.config.manager.testingservices.seviceinterface.TestingScheduledThreadPoolServiceInterface; import org.opendaylight.controller.config.manager.testingservices.seviceinterface.TestingThreadPoolServiceInterface; import org.opendaylight.controller.config.spi.Module; import org.opendaylight.yangtools.concepts.Identifiable; -import com.google.common.collect.Sets; - public class InterfacesHelperTest { interface SuperA { @@ -46,10 +45,19 @@ public class InterfacesHelperTest { } + @ServiceInterfaceAnnotation(value = "a", osgiRegistrationType = SuperA.class, namespace = "n", revision = "r", localName = "l") + interface Service extends AbstractServiceInterface{} + @ServiceInterfaceAnnotation(value = "b", osgiRegistrationType = SuperC.class, namespace = "n", revision = "r", localName = "l") + interface SubService extends Service{} + abstract class SubClass extends SuperClass implements SubA, Module { } + abstract class SubClassWithService implements SubService, Module { + + } + @Test public void testGetAllInterfaces() { Set> expected = Sets.> newHashSet(SuperA.class, SuperBMXBean.class, SuperC.class, @@ -58,6 +66,19 @@ public class InterfacesHelperTest { InterfacesHelper.getAllInterfaces(SubClass.class)); } + @Test + public void testGetServiceInterfaces() throws Exception { + assertEquals(Collections.>emptySet(), InterfacesHelper.getServiceInterfaces(SubClass.class)); + assertEquals(Sets.>newHashSet(Service.class, SubService.class), InterfacesHelper.getServiceInterfaces(SubClassWithService.class)); + } + + @Test + public void testGetOsgiRegistrationTypes() throws Exception { + assertEquals(Collections.>emptySet(), InterfacesHelper.getOsgiRegistrationTypes(SubClass.class)); + assertEquals(Sets.>newHashSet(SuperA.class, SuperC.class), + InterfacesHelper.getOsgiRegistrationTypes(SubClassWithService.class)); + } + @Test public void testGetMXInterfaces() { Set> expected = Sets.> newHashSet(SuperBMXBean.class, SubA.class); diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/util/OsgiRegistrationUtilTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/util/OsgiRegistrationUtilTest.java new file mode 100644 index 0000000000..fb59e3d515 --- /dev/null +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/impl/util/OsgiRegistrationUtilTest.java @@ -0,0 +1,61 @@ +package org.opendaylight.controller.config.manager.impl.util; + +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +import org.junit.Test; +import org.mockito.InOrder; +import org.mockito.Mockito; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; +import org.osgi.util.tracker.BundleTracker; +import org.osgi.util.tracker.ServiceTracker; + +public class OsgiRegistrationUtilTest { + + @Test + public void testRegisterService() throws Exception { + final BundleContext bundleContext = mock(BundleContext.class); + ServiceRegistration registration = mockServiceRegistration(); + doReturn(registration).when(bundleContext).registerService(String.class, "string", null); + ServiceRegistration registration2 = mockServiceRegistration(); + doReturn(registration2).when(bundleContext).registerService(Object.class, "string", null); + + AutoCloseable aggregatedRegister = OsgiRegistrationUtil.registerService(bundleContext, "string", String.class, Object.class); + aggregatedRegister.close(); + + InOrder inOrder = Mockito.inOrder(registration, registration2); + inOrder.verify(registration2).unregister(); + inOrder.verify(registration).unregister(); + } + + @Test + public void testWrap() throws Exception { + final ServiceRegistration serviceReg = mockServiceRegistration(); + OsgiRegistrationUtil.wrap(serviceReg).close(); + verify(serviceReg).unregister(); + + final BundleTracker tracker = mock(BundleTracker.class); + doNothing().when(tracker).close(); + OsgiRegistrationUtil.wrap(tracker).close(); + verify(tracker).close(); + + final ServiceTracker sTracker = mock(ServiceTracker.class); + doNothing().when(sTracker).close(); + OsgiRegistrationUtil.wrap(sTracker).close(); + verify(sTracker).close(); + } + + private ServiceRegistration mockServiceRegistration() { + ServiceRegistration mock = mock(ServiceRegistration.class); + doNothing().when(mock).unregister(); + return mock; + } + + @Test + public void testAggregate() throws Exception { + + } +} \ No newline at end of file diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/AbstractTestingFixedThreadPoolModuleFactory.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/AbstractTestingFixedThreadPoolModuleFactory.java index 0286400d7b..a7024ca39e 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/AbstractTestingFixedThreadPoolModuleFactory.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/AbstractTestingFixedThreadPoolModuleFactory.java @@ -9,6 +9,6 @@ package org.opendaylight.controller.config.manager.testingservices.threadpool; import org.opendaylight.yangtools.yang.binding.annotations.ModuleQName; -@ModuleQName(namespace = "namespace", revision = "revision", name = "name") +@ModuleQName(namespace = "namespace", revision = "2012-12-12", name = "name") public abstract class AbstractTestingFixedThreadPoolModuleFactory { } diff --git a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/test/SimpleConfigurationTest.java b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/test/SimpleConfigurationTest.java index 97d1c63ed2..4ba3dc8939 100644 --- a/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/test/SimpleConfigurationTest.java +++ b/opendaylight/config/config-manager/src/test/java/org/opendaylight/controller/config/manager/testingservices/threadpool/test/SimpleConfigurationTest.java @@ -380,7 +380,8 @@ public class SimpleConfigurationTest extends AbstractConfigTest { @Test public void testQNames() { Set availableModuleFactoryQNames = configRegistryClient.getAvailableModuleFactoryQNames(); - String expected = "(namespace?revision=revision)name"; + String expected = "(namespace?revision=2012-12-12)name"; + assertEquals(Sets.newHashSet(expected), availableModuleFactoryQNames); } diff --git a/opendaylight/config/config-manager/src/test/resources/module-factories/module-factory-fail b/opendaylight/config/config-manager/src/test/resources/module-factories/module-factory-fail new file mode 100644 index 0000000000..fbd810841f --- /dev/null +++ b/opendaylight/config/config-manager/src/test/resources/module-factories/module-factory-fail @@ -0,0 +1 @@ +org.opendaylight.controller.config.manager.impl.osgi.ModuleFactoryBundleTrackerTest$NotExtendingTestingFactory \ No newline at end of file diff --git a/opendaylight/config/config-manager/src/test/resources/module-factories/module-factory-ok b/opendaylight/config/config-manager/src/test/resources/module-factories/module-factory-ok new file mode 100644 index 0000000000..031b622bba --- /dev/null +++ b/opendaylight/config/config-manager/src/test/resources/module-factories/module-factory-ok @@ -0,0 +1 @@ +org.opendaylight.controller.config.manager.impl.osgi.ModuleFactoryBundleTrackerTest$TestingFactory \ No newline at end of file -- 2.36.6