Merge "BUG-444: Refactored BGP-RIB configuration modules tests."
[bgpcep.git] / bgp / rib-impl-config / src / test / java / org / opendaylight / controller / config / yang / bgp / rib / impl / RIBImplModuleTest.java
1 /*
2  * Copyright (c) 2013 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 package org.opendaylight.controller.config.yang.bgp.rib.impl;
9
10 import static org.junit.Assert.assertTrue;
11 import static org.junit.Assert.fail;
12 import static org.mockito.Matchers.any;
13 import static org.mockito.Mockito.mock;
14
15 import java.util.Arrays;
16 import java.util.Collections;
17 import java.util.List;
18 import java.util.concurrent.Future;
19
20 import javax.management.InstanceAlreadyExistsException;
21 import javax.management.InstanceNotFoundException;
22 import javax.management.ObjectName;
23
24 import org.junit.After;
25 import org.junit.Before;
26 import org.junit.Test;
27 import org.mockito.Matchers;
28 import org.mockito.Mock;
29 import org.mockito.Mockito;
30 import org.mockito.MockitoAnnotations;
31 import org.opendaylight.controller.config.api.ValidationException;
32 import org.opendaylight.controller.config.api.jmx.CommitStatus;
33 import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
34 import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
35 import org.opendaylight.controller.config.spi.ModuleFactory;
36 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
37 import org.opendaylight.controller.config.yang.bgp.parser.spi.SimpleBGPExtensionProviderContextModuleFactory;
38 import org.opendaylight.controller.config.yang.bgp.reconnectstrategy.TimedReconnectStrategyModuleTest;
39 import org.opendaylight.controller.config.yang.bgp.rib.spi.RIBExtensionsImplModuleFactory;
40 import org.opendaylight.controller.config.yang.bgp.rib.spi.RIBExtensionsImplModuleMXBean;
41 import org.opendaylight.controller.config.yang.md.sal.binding.impl.DataBrokerImplModuleFactory;
42 import org.opendaylight.controller.config.yang.md.sal.binding.impl.DataBrokerImplModuleMXBean;
43 import org.opendaylight.controller.config.yang.md.sal.binding.impl.RuntimeMappingModuleFactory;
44 import org.opendaylight.controller.config.yang.md.sal.dom.impl.DomBrokerImplModuleFactory;
45 import org.opendaylight.controller.config.yang.md.sal.dom.impl.DomBrokerImplModuleMXBean;
46 import org.opendaylight.controller.config.yang.md.sal.dom.impl.HashMapDataStoreModuleFactory;
47 import org.opendaylight.controller.config.yang.md.sal.dom.impl.HashMapDataStoreModuleMXBean;
48 import org.opendaylight.controller.config.yang.netty.eventexecutor.GlobalEventExecutorModuleFactory;
49 import org.opendaylight.controller.config.yang.netty.threadgroup.NettyThreadgroupModuleFactory;
50 import org.opendaylight.controller.config.yang.netty.timer.HashedWheelTimerModuleFactory;
51 import org.opendaylight.controller.config.yang.reconnectstrategy.TimedReconnectStrategyModuleFactory;
52 import org.opendaylight.controller.config.yang.store.impl.YangParserWrapper;
53 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
54 import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
55 import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
56 import org.opendaylight.controller.sal.core.api.data.DataProviderService;
57 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.RibId;
59 import org.opendaylight.yangtools.concepts.Registration;
60 import org.opendaylight.yangtools.yang.common.RpcResult;
61 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
62 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
63 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
64 import org.opendaylight.yangtools.yang.model.api.SchemaServiceListener;
65 import org.osgi.framework.Bundle;
66 import org.osgi.framework.BundleListener;
67 import org.osgi.framework.Filter;
68 import org.osgi.framework.ServiceListener;
69 import org.osgi.framework.ServiceReference;
70
71 import com.google.common.collect.Lists;
72
73 public class RIBImplModuleTest extends AbstractConfigTest {
74     private static final String INSTANCE_NAME = "rib-impl";
75     private static final String FACTORY_NAME = RIBImplModuleFactory.NAME;
76     private static final String TRANSACTION_NAME = "testTransaction";
77
78     private static final String RIB_ID = "test";
79     private static final String BGP_ID = "192.168.1.1";
80
81     private static final String SESSION_RS_INSTANCE_NAME = "session-reconnect-strategy-impl";
82     private static final String TCP_RS_INSTANCE_NAME = "tcp-reconnect-strategy";
83     private static final String DATA_BROKER_INSTANCE_NAME = "data-broker-impl";
84     private static final String DOM_BROKER_INSTANCE_NAME = "data-broker-impl";
85     private static final String DATA_STORE_INSTANCE_NAME = "data-store-impl";
86     private static final String RIB_EXTENSIONS_INSTANCE_NAME = "rib-extensions-impl";
87
88     @Mock
89     private DataModificationTransaction mockedTransaction;
90
91     @Mock
92     private DataProviderService mockedDataProvider;
93
94     @Mock
95     private Future<RpcResult<TransactionStatus>> mockedFuture;
96
97     @Mock
98     private RpcResult<TransactionStatus> mockedResult;
99
100     @SuppressWarnings("unchecked")
101     @Before
102     public void setUp() throws Exception {
103         MockitoAnnotations.initMocks(this);
104
105         List<ModuleFactory> moduleFactories = getModuleFactories();
106         super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, moduleFactories
107                 .toArray(new ModuleFactory[moduleFactories.size()])));
108
109         Filter mockedFilter = mock(Filter.class);
110         Mockito.doReturn(mockedFilter).when(mockedContext).createFilter(Mockito.anyString());
111
112         Mockito.doNothing().when(mockedContext).addServiceListener(any(ServiceListener.class), Mockito.anyString());
113
114         Mockito.doNothing().when(mockedContext).addBundleListener(any(BundleListener.class));
115
116         Mockito.doReturn(new Bundle[] {}).when(mockedContext).getBundles();
117
118         Mockito.doReturn(new ServiceReference[] {}).when(mockedContext)
119                 .getServiceReferences(Matchers.anyString(), Matchers.anyString());
120
121         ServiceReference<?> emptyServiceReference = mock(ServiceReference.class, "Empty");
122
123         ServiceReference<?> dataProviderServiceReference = mock(ServiceReference.class, "Data Provider");
124
125         Mockito.doReturn(mockedFilter).when(mockedContext).createFilter(Mockito.anyString());
126
127         Mockito.doNothing().when(mockedContext).addServiceListener(any(ServiceListener.class), Mockito.anyString());
128
129         Mockito.doNothing().when(mockedContext).addBundleListener(any(BundleListener.class));
130
131         Mockito.doReturn(new Bundle[] {}).when(mockedContext).getBundles();
132
133         Mockito.doReturn(new ServiceReference[] {}).when(mockedContext)
134                 .getServiceReferences(Matchers.anyString(), Matchers.anyString());
135
136         // mockedDataProvider = mock(DataProviderService.class);
137
138         Mockito.doReturn("Empty reference").when(emptyServiceReference).toString();
139         Mockito.doReturn("Data Provider Service Reference").when(dataProviderServiceReference).toString();
140         //
141         Mockito.doReturn(emptyServiceReference).when(mockedContext).getServiceReference(any(Class.class));
142         Mockito.doReturn(dataProviderServiceReference).when(mockedContext)
143                 .getServiceReference(DataProviderService.class);
144
145         Mockito.doReturn(mockedDataProvider).when(mockedContext).getService(dataProviderServiceReference);
146
147         // Mockito.doReturn(null).when(mockedContext).getService(dataProviderServiceReference);
148         Mockito.doReturn(null).when(mockedContext).getService(emptyServiceReference);
149
150         Registration<DataCommitHandler<InstanceIdentifier, CompositeNode>> registration = mock(Registration.class);
151         Mockito.doReturn(registration).when(mockedDataProvider)
152                 .registerCommitHandler(any(InstanceIdentifier.class), any(DataCommitHandler.class));
153         Mockito.doReturn(registration).when(mockedDataProvider)
154                 .registerCommitHandler(any(InstanceIdentifier.class), any(DataCommitHandler.class));
155
156         Mockito.doReturn(null).when(mockedDataProvider).readOperationalData(any(InstanceIdentifier.class));
157         Mockito.doReturn(mockedTransaction).when(mockedDataProvider).beginTransaction();
158
159         Mockito.doNothing().when(mockedTransaction)
160                 .putOperationalData(any(InstanceIdentifier.class), any(CompositeNode.class));
161         Mockito.doNothing().when(mockedTransaction).removeOperationalData(any(InstanceIdentifier.class));
162
163         Mockito.doReturn(mockedFuture).when(mockedTransaction).commit();
164         Mockito.doReturn(TRANSACTION_NAME).when(mockedTransaction).getIdentifier();
165
166         Mockito.doReturn(mockedResult).when(mockedFuture).get();
167         Mockito.doReturn(true).when(mockedResult).isSuccessful();
168         Mockito.doReturn(Collections.emptySet()).when(mockedResult).getErrors();
169     }
170
171     protected List<ModuleFactory> getModuleFactories() {
172         return Lists.newArrayList(new RIBImplModuleFactory(), new DataBrokerImplModuleFactory(),
173                 new GlobalEventExecutorModuleFactory(), new BGPDispatcherImplModuleFactory(),
174                 new NettyThreadgroupModuleFactory(), new TimedReconnectStrategyModuleFactory(),
175                 new SimpleBGPExtensionProviderContextModuleFactory(), new RIBExtensionsImplModuleFactory(),
176                 new DomBrokerImplModuleFactory(), new RuntimeMappingModuleFactory(),
177                 new HashMapDataStoreModuleFactory(), new HashedWheelTimerModuleFactory());
178     }
179
180     @Override
181     protected BundleContextServiceRegistrationHandler getBundleContextServiceRegistrationHandler(
182             final Class<?> serviceType) {
183         if (serviceType.equals(SchemaServiceListener.class)) {
184             return new BundleContextServiceRegistrationHandler() {
185                 @Override
186                 public void handleServiceRegistration(final Object o) {
187                     SchemaServiceListener listener = (SchemaServiceListener) o;
188                     listener.onGlobalContextUpdated(getMockedSchemaContext());
189                 }
190             };
191         }
192
193         return super.getBundleContextServiceRegistrationHandler(serviceType);
194     }
195
196     @Test
197     public void testValidationExceptionRibIdNotSet() throws Exception {
198         try {
199             createInstance(null, 500L, new Ipv4Address(BGP_ID));
200             fail();
201         } catch (ValidationException e) {
202             assertTrue(e.getMessage().contains("RibId is not set."));
203         }
204     }
205
206     @Test
207     public void testValidationExceptionLocalAsNotSet() throws Exception {
208         try {
209             createInstance(new RibId(RIB_ID), null, new Ipv4Address(BGP_ID));
210             fail();
211         } catch (ValidationException e) {
212             assertTrue(e.getMessage().contains("LocalAs is not set."));
213         }
214     }
215
216     @Test
217     public void testValidationExceptionBgpIdNotSet() throws Exception {
218         try {
219             createInstance(new RibId(RIB_ID), 500L, null);
220             fail();
221         } catch (ValidationException e) {
222             assertTrue(e.getMessage().contains("BgpId is not set."));
223         }
224     }
225
226     @Test
227     public void testCreateBean() throws Exception {
228         CommitStatus status = createInstance();
229         Thread.sleep(2000);
230         assertBeanCount(1, FACTORY_NAME);
231         assertStatus(status, 14, 0, 0);
232     }
233
234     @Test
235     public void testReusingOldInstance() throws Exception {
236         createInstance();
237         Thread.sleep(2000);
238         ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
239         assertBeanCount(1, FACTORY_NAME);
240         CommitStatus status = transaction.commit();
241         assertBeanCount(1, FACTORY_NAME);
242         assertStatus(status, 0, 0, 14);
243     }
244
245     @Test
246     public void testReconfigure() throws Exception {
247         createInstance();
248         Thread.sleep(2000);
249         final ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
250         assertBeanCount(1, FACTORY_NAME);
251         final RIBImplModuleMXBean mxBean = transaction.newMBeanProxy(
252                 transaction.lookupConfigBean(FACTORY_NAME, INSTANCE_NAME), RIBImplModuleMXBean.class);
253         mxBean.setLocalAs(100L);
254         final CommitStatus status = transaction.commit();
255         assertBeanCount(1, FACTORY_NAME);
256         assertStatus(status, 0, 1, 13);
257     }
258
259     @After
260     public void closeAllModules() throws Exception {
261         super.destroyAllConfigBeans();
262     }
263
264     private CommitStatus createInstance() throws Exception {
265         ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
266         createInstance(transaction);
267         return transaction.commit();
268     }
269
270     private CommitStatus createInstance(final RibId ribId, final Long localAs, final Ipv4Address bgpId)
271             throws Exception {
272         ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
273         createInstance(transaction, ribId, localAs, bgpId);
274         return transaction.commit();
275     }
276
277     private static ObjectName createInstance(final ConfigTransactionJMXClient transaction, final RibId ribId,
278             final Long localAs, final Ipv4Address bgpId) throws Exception {
279         ObjectName nameCreated = transaction.createModule(RIBImplModuleFactory.NAME, INSTANCE_NAME);
280         RIBImplModuleMXBean mxBean = transaction.newMXBeanProxy(nameCreated, RIBImplModuleMXBean.class);
281         ObjectName reconnectObjectName = TimedReconnectStrategyModuleTest.createInstance(transaction,
282                 SESSION_RS_INSTANCE_NAME);
283         mxBean.setSessionReconnectStrategy(reconnectObjectName);
284         mxBean.setDataProvider(createDataBrokerInstance(transaction));
285         ObjectName reconnectStrategyON = TimedReconnectStrategyModuleTest.createInstance(transaction,
286                 TCP_RS_INSTANCE_NAME);
287         mxBean.setTcpReconnectStrategy(reconnectStrategyON);
288         mxBean.setBgpDispatcher(BGPDispatcherImplModuleTest.createInstance(transaction));
289         mxBean.setExtensions(createRibExtensionsInstance(transaction));
290         mxBean.setRibId(ribId);
291         mxBean.setLocalAs(localAs);
292         mxBean.setBgpId(bgpId);
293         return nameCreated;
294     }
295
296     public static ObjectName createInstance(final ConfigTransactionJMXClient transaction) throws Exception {
297         return createInstance(transaction, new RibId(RIB_ID), 5000L, new Ipv4Address(BGP_ID));
298     }
299
300     private static ObjectName createDataBrokerInstance(final ConfigTransactionJMXClient transaction)
301             throws InstanceAlreadyExistsException, InstanceNotFoundException {
302         ObjectName nameCreated = transaction.createModule(DataBrokerImplModuleFactory.NAME, DATA_BROKER_INSTANCE_NAME);
303         DataBrokerImplModuleMXBean mxBean = transaction.newMBeanProxy(nameCreated, DataBrokerImplModuleMXBean.class);
304         mxBean.setDomBroker(createDomBrokerInstance(transaction));
305         mxBean.setMappingService(lookupMappingServiceInstance(transaction));
306         return nameCreated;
307     }
308
309     private static ObjectName createDomBrokerInstance(final ConfigTransactionJMXClient transaction)
310             throws InstanceAlreadyExistsException {
311         ObjectName nameCreated = transaction.createModule(DomBrokerImplModuleFactory.NAME, DOM_BROKER_INSTANCE_NAME);
312         DomBrokerImplModuleMXBean mxBean = transaction.newMBeanProxy(nameCreated, DomBrokerImplModuleMXBean.class);
313         mxBean.setDataStore(createDataStoreInstance(transaction));
314         return nameCreated;
315     }
316
317     private static ObjectName createDataStoreInstance(final ConfigTransactionJMXClient transaction)
318             throws InstanceAlreadyExistsException {
319         ObjectName nameCreated = transaction.createModule(HashMapDataStoreModuleFactory.NAME, DATA_STORE_INSTANCE_NAME);
320         transaction.newMBeanProxy(nameCreated, HashMapDataStoreModuleMXBean.class);
321         return nameCreated;
322     }
323
324     private static ObjectName lookupMappingServiceInstance(final ConfigTransactionJMXClient transaction) {
325
326         try {
327             return transaction.lookupConfigBean(RuntimeMappingModuleFactory.NAME,
328                     RuntimeMappingModuleFactory.SINGLETON_NAME);
329         } catch (InstanceNotFoundException e) {
330             try {
331                 return transaction.createModule(RuntimeMappingModuleFactory.NAME,
332                         RuntimeMappingModuleFactory.SINGLETON_NAME);
333             } catch (InstanceAlreadyExistsException e1) {
334                 throw new IllegalStateException(e1);
335             }
336         }
337     }
338
339     private static ObjectName createRibExtensionsInstance(final ConfigTransactionJMXClient transaction)
340             throws InstanceAlreadyExistsException {
341         ObjectName nameCreated = transaction.createModule(RIBExtensionsImplModuleFactory.NAME,
342                 RIB_EXTENSIONS_INSTANCE_NAME);
343         transaction.newMBeanProxy(nameCreated, RIBExtensionsImplModuleMXBean.class);
344         return nameCreated;
345     }
346
347     public SchemaContext getMockedSchemaContext() {
348         List<String> paths = Arrays.asList("/META-INF/yang/bgp-rib.yang", "/META-INF/yang/ietf-inet-types.yang",
349                 "/META-INF/yang/bgp-message.yang", "/META-INF/yang/bgp-multiprotocol.yang",
350                 "/META-INF/yang/bgp-types.yang");
351         return YangParserWrapper.parseYangFiles(getFilesAsInputStreams(paths));
352     }
353 }