9ac570e2eed166045ac7930425b77932b5229263
[controller.git] / opendaylight / config / config-manager / src / test / java / org / opendaylight / controller / config / manager / impl / osgi / ModuleFactoryBundleTrackerTest.java
1 /*
2  * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.controller.config.manager.impl.osgi;
10
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertNotNull;
13 import static org.junit.Assert.fail;
14 import static org.mockito.Matchers.any;
15 import static org.mockito.Matchers.anyObject;
16 import static org.mockito.Matchers.anyString;
17 import static org.mockito.Mockito.doAnswer;
18 import static org.mockito.Mockito.doNothing;
19 import static org.mockito.Mockito.doReturn;
20 import static org.mockito.Mockito.mock;
21 import static org.mockito.Mockito.verify;
22 import static org.mockito.Mockito.verifyZeroInteractions;
23 import java.util.Collection;
24 import java.util.Dictionary;
25 import java.util.Map.Entry;
26 import java.util.Set;
27 import org.junit.Before;
28 import org.junit.Test;
29 import org.mockito.Mock;
30 import org.mockito.MockitoAnnotations;
31 import org.mockito.invocation.InvocationOnMock;
32 import org.mockito.stubbing.Answer;
33 import org.opendaylight.controller.config.api.DependencyResolver;
34 import org.opendaylight.controller.config.api.DependencyResolverFactory;
35 import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
36 import org.opendaylight.controller.config.api.annotations.AbstractServiceInterface;
37 import org.opendaylight.controller.config.spi.Module;
38 import org.opendaylight.controller.config.spi.ModuleFactory;
39 import org.osgi.framework.Bundle;
40 import org.osgi.framework.BundleContext;
41 import org.osgi.framework.BundleEvent;
42 import org.osgi.framework.ServiceRegistration;
43
44 public class ModuleFactoryBundleTrackerTest {
45
46     @Mock
47     private Bundle bundle;
48     @Mock
49     private BundleContext context;
50     @Mock
51     private ServiceRegistration<?> reg;
52     @Mock
53     private BlankTransactionServiceTracker blankTxTracker;
54
55     @Before
56     public void setUp() throws Exception {
57         MockitoAnnotations.initMocks(this);
58         doAnswer(new Answer<Object>() {
59             @Override
60             public Object answer(final InvocationOnMock invocation) throws Throwable {
61                 return getClass().getClassLoader().loadClass((String) invocation.getArguments()[0]);
62             }
63         }).when(bundle).loadClass(anyString());
64         doReturn("mockBundle").when(bundle).toString();
65         doReturn("mockBundleContext").when(context).toString();
66         doReturn(context).when(bundle).getBundleContext();
67         doReturn(100L).when(bundle).getBundleId();
68         doReturn(reg).when(context).registerService(anyString(), anyObject(), any(Dictionary.class));
69     }
70
71     @Test
72     public void testRegisterFactory() throws Exception {
73         Entry<ModuleFactory, Bundle> entry = ModuleFactoryBundleTracker.registerFactory(
74                 TestingFactory.class.getName(), bundle);
75         assertEquals(TestingFactory.currentInstance, entry.getKey());
76         assertEquals(bundle, entry.getValue());
77     }
78
79     @Test
80     public void testRegisterFactoryInstantiateEx() throws Exception {
81         try {
82             ModuleFactoryBundleTracker.registerFactory(WrongConstructorTestingFactory.class.getName(), bundle);
83         } catch (Exception e) {
84             verifyZeroInteractions(context);
85             assertNotNull(e.getCause());
86             assertEquals(InstantiationException.class, e.getCause().getClass());
87             return;
88         }
89
90         fail("Cannot register without proper constructor");
91     }
92
93     @Test
94     public void testRegisterFactoryInstantiateExAccess() throws Exception {
95         try {
96             ModuleFactoryBundleTracker.registerFactory(NoAccessConstructorTestingFactory.class.getName(), bundle);
97         } catch (Exception e) {
98             verifyZeroInteractions(context);
99             assertNotNull(e.getCause());
100             assertEquals(IllegalAccessException.class, e.getCause().getClass());
101             return;
102         }
103
104         fail("Cannot register without proper constructor");
105     }
106
107     @Test
108     public void testRegisterFactoryNotExtending() throws Exception {
109         try {
110             ModuleFactoryBundleTracker.registerFactory(NotExtendingTestingFactory.class.getName(), bundle);
111         } catch (Exception e) {
112             verifyZeroInteractions(context);
113             return;
114         }
115
116         fail("Cannot register without extend");
117     }
118
119     @Test
120     public void testRegisterFactoryNotExisting() throws Exception {
121         try {
122             ModuleFactoryBundleTracker.registerFactory("Unknown class", bundle);
123         } catch (Exception e) {
124             verifyZeroInteractions(context);
125             assertNotNull(e.getCause());
126             assertEquals(ClassNotFoundException.class, e.getCause().getClass());
127             return;
128         }
129
130         fail("Cannot register without extend");
131     }
132
133     @Test
134     public void testBundleAddAndRemove() throws Exception {
135         final ModuleFactoryBundleTracker tracker = new ModuleFactoryBundleTracker(blankTxTracker);
136         doReturn(getClass().getResource("/module-factories/module-factory-ok")).when(bundle).getEntry(anyString());
137         tracker.addingBundle(bundle, mock(BundleEvent.class));
138
139         Collection<Entry<ModuleFactory, BundleContext>> entries = tracker.getModuleFactoryEntries();
140         assertNotNull(entries);
141         assertEquals(1, entries.size());
142         Entry<ModuleFactory, BundleContext> entry = entries.iterator().next();
143         assertEquals(TestingFactory.currentInstance, entry.getKey());
144         assertEquals(context, entry.getValue());
145
146         doNothing().when(blankTxTracker).blankTransaction();;
147
148         tracker.removedBundle(bundle, mock(BundleEvent.class), bundle);
149
150         entries = tracker.getModuleFactoryEntries();
151         assertNotNull(entries);
152         assertEquals(0, entries.size());
153
154         verify(blankTxTracker).blankTransaction();;
155     }
156
157     @Test
158     public void testAddingBundleError() throws Exception {
159         final ModuleFactoryBundleTracker tracker = new ModuleFactoryBundleTracker(blankTxTracker);
160         doReturn(getClass().getResource("/module-factories/module-factory-fail")).when(bundle).getEntry(anyString());
161         try {
162             tracker.addingBundle(bundle, mock(BundleEvent.class));
163         } catch (Exception e) {
164             verifyZeroInteractions(context);
165             return;
166         }
167
168         fail("Cannot register");
169     }
170
171     static class WrongConstructorTestingFactory extends TestingFactory {
172         WrongConstructorTestingFactory(final String randomParam) {
173         }
174     }
175
176     static class NotExtendingTestingFactory {}
177
178     static class NoAccessConstructorTestingFactory extends TestingFactory {
179         private NoAccessConstructorTestingFactory() {
180         }
181     }
182
183     static class TestingFactory implements ModuleFactory {
184
185         static TestingFactory currentInstance;
186
187         TestingFactory() {
188             currentInstance = this;
189         }
190
191         @Override
192         public String getImplementationName() {
193             return "Testing";
194         }
195
196         @Override
197         public Module createModule(final String instanceName, final DependencyResolver dependencyResolver, final BundleContext bundleContext) {
198             throw new UnsupportedOperationException();
199         }
200
201         @Override
202         public Module createModule(final String instanceName, final DependencyResolver dependencyResolver, final DynamicMBeanWithInstance old, final BundleContext bundleContext) throws Exception {
203             throw new UnsupportedOperationException();
204         }
205
206         @Override
207         public boolean isModuleImplementingServiceInterface(final Class<? extends AbstractServiceInterface> serviceInterface) {
208             throw new UnsupportedOperationException();
209         }
210
211         @Override
212         public Set<Class<? extends AbstractServiceInterface>> getImplementedServiceIntefaces() {
213             throw new UnsupportedOperationException();
214         }
215
216         @Override
217         public Set<? extends Module> getDefaultModules(final DependencyResolverFactory dependencyResolverFactory, final BundleContext bundleContext) {
218             throw new UnsupportedOperationException();
219         }
220     }
221 }