2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.protocol.bgp.rib.impl.config;
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;
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.api.ClusterSingletonServiceProvider;
38 import org.opendaylight.protocol.bgp.openconfig.routing.policy.impl.DefaultBGPRibRoutingPolicyFactory;
39 import org.opendaylight.protocol.bgp.openconfig.routing.policy.spi.registry.StatementRegistry;
40 import org.opendaylight.protocol.bgp.openconfig.spi.BGPTableTypeRegistryConsumer;
41 import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl;
42 import org.opendaylight.protocol.bgp.rib.impl.DefaultRibPoliciesMockTest;
43 import org.opendaylight.protocol.bgp.rib.impl.protocol.BGPReconnectPromise;
44 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPDispatcher;
45 import org.opendaylight.protocol.bgp.rib.impl.spi.CodecsRegistry;
46 import org.opendaylight.protocol.bgp.rib.impl.state.BGPStateCollector;
47 import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
48 import org.opendaylight.protocol.bgp.rib.spi.state.BGPStateProviderRegistry;
49 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.Bgp;
50 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Global;
51 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Neighbors;
52 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.OpenconfigNetworkInstanceData;
53 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.NetworkInstances;
54 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.NetworkInstance;
55 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.NetworkInstanceKey;
56 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.Protocols;
57 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.protocols.Protocol;
58 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.protocols.ProtocolKey;
59 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.policy.types.rev151009.BGP;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.BgpTableType;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NetworkInstanceProtocol;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.Ipv4AddressFamily;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.UnicastSubsequentAddressFamily;
64 import org.opendaylight.yangtools.concepts.Registration;
65 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
66 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
68 public class BgpDeployerTest extends DefaultRibPoliciesMockTest {
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;
85 private BGPTableTypeRegistryConsumer tableTypeRegistry;
87 private BGPDispatcher dispatcher;
89 private CodecsRegistry codecsRegistry;
91 private RpcProviderService rpcRegistry;
93 private RIBExtensionConsumerContext extensionContext;
96 private ClusterSingletonServiceProvider singletonServiceProvider;
98 private final BGPStateProviderRegistry stateProviderRegistry = new BGPStateCollector();
99 private DefaultBgpDeployer deployer;
100 private BGPClusterSingletonService spiedBgpSingletonService;
101 private CountDownLatch bgpSingletonObtainedLatch;
105 public void setUp() throws Exception {
108 doReturn("mapping").when(tableTypeRegistry).toString();
109 doReturn(TABLE_TYPE).when(tableTypeRegistry).getTableType(any());
110 doReturn(TABLES_KEY).when(tableTypeRegistry).getTableKey(any());
112 final var serviceRegistration = mock(Registration.class);
113 doReturn(serviceRegistration).when(singletonServiceProvider).registerClusterSingletonService(any());
114 doNothing().when(serviceRegistration).close();
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);
130 bgpSingletonObtainedLatch.countDown();
131 return spiedBgpSingletonService;
133 ).when(deployer).getBgpClusterSingleton(any());
137 public void testDeployerRib() throws Exception {
139 checkPresentConfiguration(getDataBroker(), NETWORK_II);
140 createRib(createGlobalIpv4());
141 awaitForObtainedSingleton();
142 verify(spiedBgpSingletonService, timeout(VERIFY_TIMEOUT_MILIS).times(1)).initiateRibInstance(any());
144 //change with same rib already existing
145 createRib(createGlobalIpv4());
146 awaitForObtainedSingleton();
147 verify(spiedBgpSingletonService, timeout(VERIFY_TIMEOUT_MILIS).times(1)).initiateRibInstance(any());
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();
155 //Delete for existing rib
157 awaitForObtainedSingleton();
158 verify(spiedBgpSingletonService, timeout(VERIFY_TIMEOUT_MILIS).times(2)).initiateRibInstance(any());
159 verify(spiedBgpSingletonService, timeout(VERIFY_TIMEOUT_MILIS).times(2)).closeRibInstance();
165 public void testDeployerCreateNeighbor() throws Exception {
167 checkPresentConfiguration(getDataBroker(), NETWORK_II);
169 createRib(createGlobalIpv4());
170 createNeighbor(createNeighbors());
171 awaitForObtainedSingleton();
172 verify(spiedBgpSingletonService, timeout(VERIFY_TIMEOUT_MILIS)).onNeighborCreated(any());
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());
182 createNeighbor(createNeighborsNoRR());
183 awaitForObtainedSingleton();
184 verify(spiedBgpSingletonService, timeout(VERIFY_TIMEOUT_MILIS).times(1)).onNeighborUpdated(any(), any());
187 //Delete existing Peer
188 awaitForObtainedSingleton();
189 verify(spiedBgpSingletonService, timeout(VERIFY_TIMEOUT_MILIS).times(1)).onNeighborRemoved(any());
193 private void awaitForObtainedSingleton() throws InterruptedException {
194 bgpSingletonObtainedLatch = new CountDownLatch(1);
195 bgpSingletonObtainedLatch.await(VERIFY_TIMEOUT_MILIS, TimeUnit.MILLISECONDS);
198 private void createRib(final Global global) throws ExecutionException, InterruptedException {
199 final WriteTransaction wr = getDataBroker().newWriteOnlyTransaction();
200 wr.mergeParentStructurePut(LogicalDatastoreType.CONFIGURATION, GLOBAL_II, global);
204 private void deleteRib() throws ExecutionException, InterruptedException {
205 final WriteTransaction wr = getDataBroker().newWriteOnlyTransaction();
206 wr.delete(LogicalDatastoreType.CONFIGURATION, BGP_II);
210 private void createNeighbor(final Neighbors neighbors) throws ExecutionException, InterruptedException {
211 final WriteTransaction wr = getDataBroker().newWriteOnlyTransaction();
212 wr.mergeParentStructurePut(LogicalDatastoreType.CONFIGURATION, NEIGHBORS_II, neighbors);
216 private void deleteNeighbors() throws ExecutionException, InterruptedException {
217 final WriteTransaction wr = getDataBroker().newWriteOnlyTransaction();
218 wr.delete(LogicalDatastoreType.CONFIGURATION, NEIGHBORS_II);