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