ad9e0e23de1cd4d4c7629b0bf07af709e926df9c
[bgpcep.git] / bgp / rib-impl / src / test / java / org / opendaylight / protocol / bgp / rib / impl / config / BgpDeployerTest.java
1 /*
2  * Copyright (c) 2016 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.protocol.bgp.rib.impl.config;
9
10 import static org.mockito.ArgumentMatchers.any;
11 import static org.mockito.ArgumentMatchers.anyInt;
12 import static org.mockito.Mockito.doAnswer;
13 import static org.mockito.Mockito.doNothing;
14 import static org.mockito.Mockito.doReturn;
15 import static org.mockito.Mockito.mock;
16 import static org.mockito.Mockito.never;
17 import static org.mockito.Mockito.spy;
18 import static org.mockito.Mockito.timeout;
19 import static org.mockito.Mockito.verify;
20 import static org.opendaylight.protocol.bgp.rib.impl.config.AbstractConfig.TABLES_KEY;
21 import static org.opendaylight.protocol.bgp.rib.impl.config.RIBTestsUtil.createGlobalIpv4;
22 import static org.opendaylight.protocol.bgp.rib.impl.config.RIBTestsUtil.createGlobalIpv6;
23 import static org.opendaylight.protocol.bgp.rib.impl.config.RIBTestsUtil.createNeighbors;
24 import static org.opendaylight.protocol.bgp.rib.impl.config.RIBTestsUtil.createNeighborsNoRR;
25 import static org.opendaylight.protocol.util.CheckUtil.checkPresentConfiguration;
26
27 import io.netty.util.concurrent.Future;
28 import java.util.concurrent.CountDownLatch;
29 import java.util.concurrent.ExecutionException;
30 import java.util.concurrent.TimeUnit;
31 import org.junit.Before;
32 import org.junit.Test;
33 import org.mockito.Mock;
34 import org.opendaylight.mdsal.binding.api.RpcProviderService;
35 import org.opendaylight.mdsal.binding.api.WriteTransaction;
36 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
37 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
38 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
39 import org.opendaylight.protocol.bgp.openconfig.routing.policy.impl.DefaultBGPRibRoutingPolicyFactory;
40 import org.opendaylight.protocol.bgp.openconfig.routing.policy.spi.registry.StatementRegistry;
41 import org.opendaylight.protocol.bgp.openconfig.spi.BGPTableTypeRegistryConsumer;
42 import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl;
43 import org.opendaylight.protocol.bgp.rib.impl.DefaultRibPoliciesMockTest;
44 import org.opendaylight.protocol.bgp.rib.impl.protocol.BGPReconnectPromise;
45 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPDispatcher;
46 import org.opendaylight.protocol.bgp.rib.impl.spi.CodecsRegistry;
47 import org.opendaylight.protocol.bgp.rib.impl.state.BGPStateCollector;
48 import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
49 import org.opendaylight.protocol.bgp.rib.spi.state.BGPStateProviderRegistry;
50 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.Bgp;
51 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Global;
52 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Neighbors;
53 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.OpenconfigNetworkInstanceData;
54 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.NetworkInstances;
55 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.NetworkInstance;
56 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.NetworkInstanceKey;
57 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.Protocols;
58 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.protocols.Protocol;
59 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.protocols.ProtocolKey;
60 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.policy.types.rev151009.BGP;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.BgpTableType;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NetworkInstanceProtocol;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.Ipv4AddressFamily;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.UnicastSubsequentAddressFamily;
65 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
66 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
67
68 public class BgpDeployerTest extends DefaultRibPoliciesMockTest {
69
70     private static final BgpTableType TABLE_TYPE = new BgpTableTypeImpl(Ipv4AddressFamily.VALUE,
71             UnicastSubsequentAddressFamily.VALUE);
72     private static final String NETWORK_INSTANCE_NAME = "network-test";
73     private static final KeyedInstanceIdentifier<NetworkInstance, NetworkInstanceKey> NETWORK_II =
74         InstanceIdentifier.builderOfInherited(OpenconfigNetworkInstanceData.class, NetworkInstances.class).build()
75             .child(NetworkInstance.class, new NetworkInstanceKey(NETWORK_INSTANCE_NAME));
76     private static final String KEY = "bgp";
77     private static final InstanceIdentifier<Bgp> BGP_II = NETWORK_II.child(Protocols.class)
78             .child(Protocol.class, new ProtocolKey(BGP.VALUE, KEY))
79             .augmentation(NetworkInstanceProtocol.class).child(Bgp.class);
80     private static final InstanceIdentifier<Global> GLOBAL_II = BGP_II.child(Global.class);
81     private static final InstanceIdentifier<Neighbors> NEIGHBORS_II = BGP_II.child(Neighbors.class);
82     private static final int VERIFY_TIMEOUT_MILIS = 5000;
83
84     @Mock
85     private BGPTableTypeRegistryConsumer tableTypeRegistry;
86     @Mock
87     private BGPDispatcher dispatcher;
88     @Mock
89     private CodecsRegistry codecsRegistry;
90     @Mock
91     private RpcProviderService rpcRegistry;
92     @Mock
93     private RIBExtensionConsumerContext extensionContext;
94
95     @Mock
96     private ClusterSingletonServiceProvider singletonServiceProvider;
97
98     private final BGPStateProviderRegistry stateProviderRegistry = new BGPStateCollector();
99     private DefaultBgpDeployer deployer;
100     private BGPClusterSingletonService spiedBgpSingletonService;
101     private CountDownLatch bgpSingletonObtainedLatch;
102
103     @Override
104     @Before
105     public void setUp() throws Exception {
106         super.setUp();
107
108         doReturn("mapping").when(tableTypeRegistry).toString();
109         doReturn(TABLE_TYPE).when(tableTypeRegistry).getTableType(any());
110         doReturn(TABLES_KEY).when(tableTypeRegistry).getTableKey(any());
111
112         final ClusterSingletonServiceRegistration serviceRegistration = mock(ClusterSingletonServiceRegistration.class);
113         doReturn(serviceRegistration).when(singletonServiceProvider).registerClusterSingletonService(any());
114         doNothing().when(serviceRegistration).close();
115
116         final Future future = mock(BGPReconnectPromise.class);
117         doReturn(true).when(future).cancel(true);
118         doReturn(future).when(dispatcher).createReconnectingClient(any(), any(), anyInt(), any());
119         deployer = spy(new DefaultBgpDeployer(NETWORK_INSTANCE_NAME, singletonServiceProvider,
120                 rpcRegistry, extensionContext, dispatcher,
121                 new DefaultBGPRibRoutingPolicyFactory(getDataBroker(), new StatementRegistry()),
122                 codecsRegistry, getDomBroker(), getDataBroker(), tableTypeRegistry, stateProviderRegistry));
123         bgpSingletonObtainedLatch = new CountDownLatch(1);
124         doAnswer(invocationOnMock -> {
125                 final BGPClusterSingletonService real =
126                         (BGPClusterSingletonService) invocationOnMock.callRealMethod();
127                 if (spiedBgpSingletonService == null) {
128                     spiedBgpSingletonService = spy(real);
129                 }
130                 bgpSingletonObtainedLatch.countDown();
131                 return spiedBgpSingletonService;
132             }
133         ).when(deployer).getBgpClusterSingleton(any());
134     }
135
136     @Test
137     public void testDeployerRib() throws Exception {
138         deployer.init();
139         checkPresentConfiguration(getDataBroker(), NETWORK_II);
140         createRib(createGlobalIpv4());
141         awaitForObtainedSingleton();
142         verify(spiedBgpSingletonService, timeout(VERIFY_TIMEOUT_MILIS).times(1)).initiateRibInstance(any());
143
144         //change with same rib already existing
145         createRib(createGlobalIpv4());
146         awaitForObtainedSingleton();
147         verify(spiedBgpSingletonService, timeout(VERIFY_TIMEOUT_MILIS).times(1)).initiateRibInstance(any());
148
149         //Update for existing rib
150         createRib(createGlobalIpv6());
151         awaitForObtainedSingleton();
152         verify(spiedBgpSingletonService, timeout(VERIFY_TIMEOUT_MILIS).times(2)).initiateRibInstance(any());
153         verify(spiedBgpSingletonService, timeout(VERIFY_TIMEOUT_MILIS).times(1)).closeRibInstance();
154
155         //Delete for existing rib
156         deleteRib();
157         awaitForObtainedSingleton();
158         verify(spiedBgpSingletonService, timeout(VERIFY_TIMEOUT_MILIS).times(2)).initiateRibInstance(any());
159         verify(spiedBgpSingletonService, timeout(VERIFY_TIMEOUT_MILIS).times(2)).closeRibInstance();
160
161         deployer.close();
162     }
163
164     @Test
165     public void testDeployerCreateNeighbor() throws Exception {
166         deployer.init();
167         checkPresentConfiguration(getDataBroker(), NETWORK_II);
168
169         createRib(createGlobalIpv4());
170         createNeighbor(createNeighbors());
171         awaitForObtainedSingleton();
172         verify(spiedBgpSingletonService, timeout(VERIFY_TIMEOUT_MILIS)).onNeighborCreated(any());
173
174         //change with same peer already existing
175         createNeighbor(createNeighbors());
176         awaitForObtainedSingleton();
177         verify(spiedBgpSingletonService, timeout(VERIFY_TIMEOUT_MILIS)).onNeighborCreated(any());
178         verify(spiedBgpSingletonService, never()).onNeighborRemoved(any());
179         verify(spiedBgpSingletonService, never()).onNeighborUpdated(any(), any());
180
181         //Update for peer
182         createNeighbor(createNeighborsNoRR());
183         awaitForObtainedSingleton();
184         verify(spiedBgpSingletonService, timeout(VERIFY_TIMEOUT_MILIS).times(1)).onNeighborUpdated(any(), any());
185
186         deleteNeighbors();
187         //Delete existing Peer
188         awaitForObtainedSingleton();
189         verify(spiedBgpSingletonService, timeout(VERIFY_TIMEOUT_MILIS).times(1)).onNeighborRemoved(any());
190         deployer.close();
191     }
192
193     private void awaitForObtainedSingleton() throws InterruptedException {
194         bgpSingletonObtainedLatch = new CountDownLatch(1);
195         bgpSingletonObtainedLatch.await(VERIFY_TIMEOUT_MILIS, TimeUnit.MILLISECONDS);
196     }
197
198     private void createRib(final Global global) throws ExecutionException, InterruptedException {
199         final WriteTransaction wr = getDataBroker().newWriteOnlyTransaction();
200         wr.mergeParentStructurePut(LogicalDatastoreType.CONFIGURATION, GLOBAL_II, global);
201         wr.commit().get();
202     }
203
204     private void deleteRib() throws ExecutionException, InterruptedException {
205         final WriteTransaction wr = getDataBroker().newWriteOnlyTransaction();
206         wr.delete(LogicalDatastoreType.CONFIGURATION, BGP_II);
207         wr.commit().get();
208     }
209
210     private void createNeighbor(final Neighbors neighbors) throws ExecutionException, InterruptedException {
211         final WriteTransaction wr = getDataBroker().newWriteOnlyTransaction();
212         wr.mergeParentStructurePut(LogicalDatastoreType.CONFIGURATION, NEIGHBORS_II, neighbors);
213         wr.commit().get();
214     }
215
216     private void deleteNeighbors() throws ExecutionException, InterruptedException {
217         final WriteTransaction wr = getDataBroker().newWriteOnlyTransaction();
218         wr.delete(LogicalDatastoreType.CONFIGURATION, NEIGHBORS_II);
219         wr.commit().get();
220     }
221 }