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.state;
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertTrue;
12 import static org.mockito.ArgumentMatchers.any;
13 import static org.mockito.ArgumentMatchers.anyBoolean;
14 import static org.mockito.ArgumentMatchers.anyLong;
15 import static org.mockito.ArgumentMatchers.eq;
16 import static org.mockito.Mockito.doAnswer;
17 import static org.mockito.Mockito.doNothing;
18 import static org.mockito.Mockito.doReturn;
19 import static org.mockito.Mockito.mock;
20 import static org.mockito.Mockito.spy;
21 import static org.mockito.Mockito.times;
22 import static org.mockito.Mockito.verify;
23 import static org.opendaylight.protocol.util.CheckUtil.checkNotPresentOperational;
24 import static org.opendaylight.protocol.util.CheckUtil.readDataOperational;
26 import com.google.common.collect.ImmutableList;
27 import com.google.common.collect.ImmutableSet;
28 import com.google.common.util.concurrent.Futures;
29 import com.google.common.util.concurrent.ListeningExecutorService;
30 import com.google.common.util.concurrent.MoreExecutors;
31 import java.math.BigDecimal;
32 import java.util.ArrayList;
33 import java.util.Arrays;
34 import java.util.Collections;
35 import java.util.List;
36 import java.util.Optional;
38 import java.util.concurrent.ScheduledExecutorService;
39 import java.util.concurrent.ScheduledFuture;
40 import java.util.concurrent.TimeUnit;
41 import java.util.concurrent.atomic.LongAdder;
42 import org.junit.Assert;
43 import org.junit.Before;
44 import org.junit.Test;
45 import org.mockito.ArgumentCaptor;
46 import org.mockito.Mock;
47 import org.mockito.MockitoAnnotations;
48 import org.opendaylight.infrautils.testutils.LogCapture;
49 import org.opendaylight.infrautils.testutils.internal.RememberingLogger;
50 import org.opendaylight.mdsal.binding.dom.adapter.test.AbstractDataBrokerTest;
51 import org.opendaylight.mdsal.binding.dom.adapter.test.AbstractDataBrokerTestCustomizer;
52 import org.opendaylight.mdsal.binding.dom.adapter.test.ConcurrentDataBrokerTestCustomizer;
53 import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
54 import org.opendaylight.mdsal.dom.spi.store.DOMStore;
55 import org.opendaylight.mdsal.dom.spi.store.DOMStoreReadWriteTransaction;
56 import org.opendaylight.mdsal.dom.spi.store.DOMStoreThreePhaseCommitCohort;
57 import org.opendaylight.mdsal.dom.spi.store.DOMStoreTransactionChain;
58 import org.opendaylight.mdsal.dom.spi.store.DOMStoreWriteTransaction;
59 import org.opendaylight.mdsal.dom.store.inmemory.InMemoryDOMDataStore;
60 import org.opendaylight.protocol.bgp.openconfig.spi.BGPTableTypeRegistryConsumer;
61 import org.opendaylight.protocol.bgp.rib.spi.State;
62 import org.opendaylight.protocol.bgp.rib.spi.state.BGPAfiSafiState;
63 import org.opendaylight.protocol.bgp.rib.spi.state.BGPErrorHandlingState;
64 import org.opendaylight.protocol.bgp.rib.spi.state.BGPGracelfulRestartState;
65 import org.opendaylight.protocol.bgp.rib.spi.state.BGPPeerMessagesState;
66 import org.opendaylight.protocol.bgp.rib.spi.state.BGPPeerState;
67 import org.opendaylight.protocol.bgp.rib.spi.state.BGPRibState;
68 import org.opendaylight.protocol.bgp.rib.spi.state.BGPSessionState;
69 import org.opendaylight.protocol.bgp.rib.spi.state.BGPStateConsumer;
70 import org.opendaylight.protocol.bgp.rib.spi.state.BGPTimersState;
71 import org.opendaylight.protocol.bgp.rib.spi.state.BGPTransportState;
72 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafi;
73 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.AfiSafiBuilder;
74 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.afi.safi.GracefulRestartBuilder;
75 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp.common.afi.safi.list.afi.safi.graceful.restart.StateBuilder;
76 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.operational.rev151009.BgpAfiSafiGracefulRestartState;
77 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.operational.rev151009.BgpNeighborState;
78 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.operational.rev151009.bgp.neighbor.prefix.counters_state.PrefixesBuilder;
79 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.graceful.restart.GracefulRestart;
80 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.AfiSafis;
81 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.AfiSafisBuilder;
82 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.ErrorHandling;
83 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.ErrorHandlingBuilder;
84 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.Timers;
85 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.TimersBuilder;
86 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.Transport;
87 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.TransportBuilder;
88 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbors.Neighbor;
89 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.peer.group.PeerGroup;
90 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.peer.group.PeerGroupBuilder;
91 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.Bgp;
92 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Global;
93 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.GlobalBuilder;
94 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.top.bgp.Neighbors;
95 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.ADDPATHS;
96 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.ASN32;
97 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.BgpCapability;
98 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.CommunityType;
99 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.GRACEFULRESTART;
100 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.IPV4UNICAST;
101 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.MPBGP;
102 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.types.rev151009.ROUTEREFRESH;
103 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.NetworkInstances;
104 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.NetworkInstance;
105 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.NetworkInstanceKey;
106 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.Protocols;
107 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.protocols.Protocol;
108 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.network.instance.rev151018.network.instance.top.network.instances.network.instance.protocols.ProtocolKey;
109 import org.opendaylight.yang.gen.v1.http.openconfig.net.yang.policy.types.rev151009.BGP;
110 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
111 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
112 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
113 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
114 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Timeticks;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.BgpNeighborStateAugmentation;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.BgpNeighborStateAugmentationBuilder;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.GlobalAfiSafiStateAugmentation;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.GlobalAfiSafiStateAugmentationBuilder;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborAfiSafiGracefulRestartStateAugmentation;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborAfiSafiGracefulRestartStateAugmentationBuilder;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborAfiSafiStateAugmentation;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborAfiSafiStateAugmentationBuilder;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborErrorHandlingStateAugmentation;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborErrorHandlingStateAugmentationBuilder;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborGracefulRestartStateAugmentation;
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborGracefulRestartStateAugmentationBuilder;
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborStateAugmentation;
128 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborTimersStateAugmentation;
129 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborTimersStateAugmentationBuilder;
130 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborTransportStateAugmentation;
131 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NeighborTransportStateAugmentationBuilder;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.NetworkInstanceProtocol;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.PeerGroupStateAugmentation;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.PeerGroupStateAugmentationBuilder;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.network.instances.network.instance.protocols.protocol.bgp.neighbors.neighbor.state.MessagesBuilder;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.network.instances.network.instance.protocols.protocol.bgp.neighbors.neighbor.state.messages.ReceivedBuilder;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.openconfig.extensions.rev180329.network.instances.network.instance.protocols.protocol.bgp.neighbors.neighbor.state.messages.SentBuilder;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.BgpRib;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.RibId;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.bgp.rib.Rib;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.bgp.rib.RibKey;
142 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.TablesKey;
143 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.BgpId;
144 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.Ipv4AddressFamily;
145 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.UnicastSubsequentAddressFamily;
146 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
147 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
148 import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
149 import org.opendaylight.yangtools.yang.common.Uint16;
150 import org.opendaylight.yangtools.yang.common.Uint32;
151 import org.opendaylight.yangtools.yang.common.Uint64;
152 import org.slf4j.LoggerFactory;
154 public class StateProviderImplTest extends AbstractDataBrokerTest {
155 private final LongAdder totalPathsCounter = new LongAdder();
156 private final LongAdder totalPrefixesCounter = new LongAdder();
157 private final PortNumber localPort = new PortNumber(Uint16.valueOf(1790));
158 private final PortNumber remotePort = new PortNumber(Uint16.valueOf(179));
159 private final Uint16 restartTime = Uint16.valueOf(15);
160 private final String ribId = "identifier-test";
161 private final InstanceIdentifier<Bgp> bgpInstanceIdentifier = InstanceIdentifier.create(NetworkInstances.class)
162 .child(NetworkInstance.class, new NetworkInstanceKey("global-bgp")).child(Protocols.class)
163 .child(Protocol.class, new ProtocolKey(BGP.class, this.ribId)).augmentation(NetworkInstanceProtocol.class)
165 static final TablesKey TABLES_KEY = new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class);
166 private final AsNumber as = new AsNumber(Uint32.valueOf(72));
167 private final BgpId bgpId = new BgpId("127.0.0.1");
168 private final IpAddress neighborAddress = new IpAddress(new Ipv4Address("127.0.0.2"));
169 private final List<Class<? extends BgpCapability>> supportedCap = Arrays.asList(ASN32.class, ROUTEREFRESH.class,
170 MPBGP.class, ADDPATHS.class, GRACEFULRESTART.class);
172 private BGPStateConsumer stateCollector;
174 private BGPTableTypeRegistryConsumer tableTypeRegistry;
176 private BGPRibState bgpRibState;
178 private BGPPeerState bgpPeerState;
180 private BGPSessionState bgpSessionState;
182 private BGPPeerMessagesState bgpPeerMessagesState;
184 private BGPTimersState timersState;
186 private BGPTransportState bgpTransportState;
188 private BGPErrorHandlingState bgpErrorHandlingState;
190 private BGPGracelfulRestartState bgpGracelfulRestartState;
192 private BGPAfiSafiState bgpAfiSafiState;
194 private final List<BGPPeerState> bgpPeerStates = new ArrayList<>();
195 private final List<BGPRibState> bgpRibStates = new ArrayList<>();
197 private InMemoryDOMDataStore realOperStore;
198 private InMemoryDOMDataStore spiedOperStore;
201 public void setUp() {
202 MockitoAnnotations.initMocks(this);
204 doReturn(Optional.of(IPV4UNICAST.class))
205 .when(this.tableTypeRegistry).getAfiSafiType(eq(TABLES_KEY));
207 doReturn(this.bgpRibStates).when(this.stateCollector).getRibStats();
208 doReturn(this.bgpPeerStates).when(this.stateCollector).getPeerStats();
210 final KeyedInstanceIdentifier<Rib, RibKey> iid = InstanceIdentifier.create(BgpRib.class)
211 .child(Rib.class, new RibKey(new RibId(this.ribId)));
212 doReturn(iid).when(this.bgpRibState).getInstanceIdentifier();
213 doReturn(this.as).when(this.bgpRibState).getAs();
214 doReturn(this.bgpId).when(this.bgpRibState).getRouteId();
216 doAnswer(invocation -> this.totalPathsCounter.longValue())
217 .when(this.bgpRibState).getTotalPathsCount();
218 doAnswer(invocation -> this.totalPrefixesCounter.longValue())
219 .when(this.bgpRibState).getTotalPrefixesCount();
220 doAnswer(invocation -> this.totalPathsCounter.longValue())
221 .when(this.bgpRibState).getPathCount(eq(TABLES_KEY));
222 doAnswer(invocation -> this.totalPrefixesCounter.longValue())
223 .when(this.bgpRibState).getPrefixesCount(eq(TABLES_KEY));
224 doAnswer(invocation -> Collections.singletonMap(TABLES_KEY,
225 this.totalPrefixesCounter.longValue())).when(this.bgpRibState).getTablesPrefixesCount();
226 doAnswer(invocation -> Collections.singletonMap(TABLES_KEY,
227 this.totalPathsCounter.longValue())).when(this.bgpRibState).getPathsCount();
230 doReturn("test-group").when(this.bgpPeerState).getGroupId();
231 doReturn(iid).when(this.bgpPeerState).getInstanceIdentifier();
232 doAnswer(invocation -> this.totalPrefixesCounter.longValue()).when(this.bgpPeerState).getTotalPrefixes();
233 doAnswer(invocation -> this.totalPathsCounter.longValue()).when(this.bgpPeerState).getTotalPathsCount();
234 doReturn(this.neighborAddress).when(this.bgpPeerState).getNeighborAddress();
235 doReturn(this.bgpSessionState).when(this.bgpPeerState).getBGPSessionState();
236 doReturn(this.bgpPeerMessagesState).when(this.bgpPeerState).getBGPPeerMessagesState();
238 doReturn(1L).when(this.bgpPeerMessagesState).getNotificationMessagesReceivedCount();
239 doReturn(1L).when(this.bgpPeerMessagesState).getNotificationMessagesSentCount();
240 doReturn(1L).when(this.bgpPeerMessagesState).getUpdateMessagesReceivedCount();
241 doReturn(1L).when(this.bgpPeerMessagesState).getUpdateMessagesSentCount();
242 doReturn(State.UP).when(this.bgpSessionState).getSessionState();
243 doReturn(true).when(this.bgpSessionState).isAddPathCapabilitySupported();
244 doReturn(true).when(this.bgpSessionState).isAsn32CapabilitySupported();
245 doReturn(true).when(this.bgpSessionState).isGracefulRestartCapabilitySupported();
246 doReturn(true).when(this.bgpSessionState).isMultiProtocolCapabilitySupported();
247 doReturn(true).when(this.bgpSessionState).isRouterRefreshCapabilitySupported();
249 doReturn(this.timersState).when(this.bgpPeerState).getBGPTimersState();
250 doReturn(10L).when(this.timersState).getNegotiatedHoldTime();
251 doReturn(10L).when(this.timersState).getUpTime();
253 doReturn(this.bgpTransportState).when(this.bgpPeerState).getBGPTransportState();
254 doReturn(this.localPort).when(this.bgpTransportState).getLocalPort();
255 doReturn(this.neighborAddress).when(this.bgpTransportState).getRemoteAddress();
256 doReturn(this.remotePort).when(this.bgpTransportState).getRemotePort();
258 doReturn(this.bgpErrorHandlingState).when(this.bgpPeerState).getBGPErrorHandlingState();
259 doReturn(1L).when(this.bgpErrorHandlingState).getErroneousUpdateReceivedCount();
261 doReturn(this.bgpGracelfulRestartState).when(this.bgpPeerState).getBGPGracelfulRestart();
262 doReturn(true).when(this.bgpGracelfulRestartState).isGracefulRestartAdvertized(any());
263 doReturn(true).when(this.bgpGracelfulRestartState).isGracefulRestartReceived(any());
264 doReturn(true).when(this.bgpGracelfulRestartState).isLocalRestarting();
265 doReturn(true).when(this.bgpGracelfulRestartState).isPeerRestarting();
266 doReturn(this.restartTime.toJava()).when(this.bgpGracelfulRestartState).getPeerRestartTime();
267 doReturn(BgpAfiSafiGracefulRestartState.Mode.BILATERAL).when(this.bgpGracelfulRestartState).getMode();
269 doReturn(this.bgpAfiSafiState).when(this.bgpPeerState).getBGPAfiSafiState();
270 doReturn(Collections.singleton(TABLES_KEY)).when(this.bgpAfiSafiState).getAfiSafisAdvertized();
271 doReturn(Collections.singleton(TABLES_KEY)).when(this.bgpAfiSafiState).getAfiSafisReceived();
272 doReturn(1L).when(this.bgpAfiSafiState).getPrefixesInstalledCount(any());
273 doReturn(2L).when(this.bgpAfiSafiState).getPrefixesReceivedCount(any());
274 doReturn(1L).when(this.bgpAfiSafiState).getPrefixesSentCount(any());
275 doReturn(true).when(this.bgpAfiSafiState).isAfiSafiSupported(any());
276 doReturn(true).when(this.bgpAfiSafiState).isGracefulRestartAdvertized(any());
277 doReturn(true).when(this.bgpAfiSafiState).isGracefulRestartReceived(any());
278 doReturn(true).when(this.bgpAfiSafiState).isLlGracefulRestartAdvertised(any());
279 doReturn(true).when(this.bgpAfiSafiState).isLlGracefulRestartReceived(any());
280 doReturn(60).when(this.bgpAfiSafiState).getLlGracefulRestartTimer(any());
284 protected Set<YangModuleInfo> getModuleInfos() throws Exception {
285 return ImmutableSet.of(BindingReflections.getModuleInfo(NetworkInstances.class),
286 BindingReflections.getModuleInfo(NetworkInstanceProtocol.class));
290 protected AbstractDataBrokerTestCustomizer createDataBrokerTestCustomizer() {
291 return new ConcurrentDataBrokerTestCustomizer(true) {
293 public DOMStore createOperationalDatastore() {
294 realOperStore = new InMemoryDOMDataStore("OPER", getDataTreeChangeListenerExecutor());
295 spiedOperStore = spy(realOperStore);
296 getSchemaService().registerSchemaContextListener(spiedOperStore);
297 return spiedOperStore;
301 public ListeningExecutorService getCommitCoordinatorExecutor() {
302 return MoreExecutors.newDirectExecutorService();
308 public void testActiveStateProvider() throws Exception {
309 doReturn(true).when(this.bgpRibState).isActive();
310 doReturn(true).when(this.bgpPeerState).isActive();
312 final StateProviderImpl stateProvider = new StateProviderImpl(getDataBroker(), 1, this.tableTypeRegistry,
313 this.stateCollector, "global-bgp");
314 stateProvider.init();
316 final Global globalExpected = buildGlobalExpected(0);
317 this.bgpRibStates.add(this.bgpRibState);
318 readDataOperational(getDataBroker(), this.bgpInstanceIdentifier, bgpRib -> {
319 final Global global = bgpRib.getGlobal();
320 assertEquals(globalExpected, global);
324 this.totalPathsCounter.increment();
325 this.totalPrefixesCounter.increment();
327 final Global globalExpected2 = buildGlobalExpected(1);
328 readDataOperational(getDataBroker(), this.bgpInstanceIdentifier, bgpRib -> {
329 final Global global = bgpRib.getGlobal();
330 assertEquals(globalExpected2, global);
334 this.totalPathsCounter.decrement();
335 this.totalPrefixesCounter.decrement();
337 final Global globalExpected3 = buildGlobalExpected(0);
338 readDataOperational(getDataBroker(), this.bgpInstanceIdentifier, bgpRib -> {
339 final Global global = bgpRib.getGlobal();
340 assertEquals(globalExpected3, global);
341 Assert.assertNull(bgpRib.getNeighbors());
342 Assert.assertNull(bgpRib.getPeerGroups());
346 this.bgpPeerStates.add(this.bgpPeerState);
347 final PeerGroup peerGroupExpected = buildGroupExpected();
349 this.totalPathsCounter.increment();
350 this.totalPrefixesCounter.increment();
352 final AfiSafis expectedAfiSafis = buildAfiSafis();
353 final ErrorHandling expectedErrorHandling = buildErrorHandling();
354 final GracefulRestart expectedGracefulRestart = buildGracefulRestart();
355 final Transport expectedTransport = buildTransport();
356 final Timers expectedTimers = buildTimers();
357 final BgpNeighborStateAugmentation expectedBgpNeighborState = buildBgpNeighborStateAugmentation();
359 readDataOperational(getDataBroker(), this.bgpInstanceIdentifier, bgpRib -> {
360 final Neighbors neighbors = bgpRib.getNeighbors();
361 Assert.assertNotNull(neighbors);
362 assertEquals(peerGroupExpected, bgpRib.getPeerGroups().getPeerGroup().get(0));
363 final Neighbor neighborResult = neighbors.getNeighbor().get(0);
364 assertEquals(this.neighborAddress, neighborResult.getNeighborAddress());
365 assertEquals(expectedAfiSafis, neighborResult.getAfiSafis());
366 assertEquals(expectedErrorHandling, neighborResult.getErrorHandling());
367 assertEquals(expectedGracefulRestart, neighborResult.getGracefulRestart());
368 assertEquals(expectedTransport, neighborResult.getTransport());
369 assertEquals(expectedTimers, neighborResult.getTimers());
370 final org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group
371 .State stateResult = neighborResult.getState();
372 assertEquals(expectedBgpNeighborState, stateResult.augmentation(BgpNeighborStateAugmentation.class));
373 assertEquals(BgpNeighborState.SessionState.ESTABLISHED, stateResult
374 .augmentation(NeighborStateAugmentation.class).getSessionState());
375 final List<Class<? extends BgpCapability>> supportedCapabilitiesResult = stateResult
376 .augmentation(NeighborStateAugmentation.class).getSupportedCapabilities();
377 Assert.assertTrue(supportedCapabilitiesResult.containsAll(this.supportedCap));
381 this.bgpRibStates.clear();
382 checkNotPresentOperational(getDataBroker(), this.bgpInstanceIdentifier);
384 stateProvider.close();
388 public void testInactiveStateProvider() throws Exception {
389 doReturn(false).when(this.bgpRibState).isActive();
390 doReturn(false).when(this.bgpPeerState).isActive();
392 final StateProviderImpl stateProvider = new StateProviderImpl(getDataBroker(), 1, this.tableTypeRegistry,
393 this.stateCollector, "global-bgp");
394 stateProvider.init();
396 this.bgpRibStates.add(this.bgpRibState);
397 checkNotPresentOperational(getDataBroker(), this.bgpInstanceIdentifier);
399 this.bgpPeerStates.add(this.bgpPeerState);
400 checkNotPresentOperational(getDataBroker(), this.bgpInstanceIdentifier);
402 this.bgpRibStates.clear();
403 checkNotPresentOperational(getDataBroker(), this.bgpInstanceIdentifier);
405 stateProvider.close();
409 public void testTransactionChainFailure() throws Exception {
410 if (!(LoggerFactory.getLogger(StateProviderImpl.class) instanceof RememberingLogger)) {
411 throw new IllegalStateException("infrautils-testutils must be on the classpath BEFORE other logger impls"
412 + LoggerFactory.getLogger(StateProviderImpl.class).getClass());
415 doReturn(true).when(this.bgpRibState).isActive();
417 this.bgpRibStates.add(this.bgpRibState);
419 ScheduledFuture<?> mockScheduledFuture = mock(ScheduledFuture.class);
420 doReturn(true).when(mockScheduledFuture).cancel(anyBoolean());
422 ScheduledExecutorService mockScheduler = mock(ScheduledExecutorService.class);
423 doReturn(mockScheduledFuture).when(mockScheduler).scheduleAtFixedRate(any(Runnable.class), anyLong(),
424 anyLong(), any(TimeUnit.class));
425 doNothing().when(mockScheduler).shutdown();
427 DOMStoreTransactionChain mockTxChain = mock(DOMStoreTransactionChain.class);
428 doNothing().when(mockTxChain).close();
430 Throwable mockCommitEx = new Exception("mock commit failure");
431 doAnswer(invocation -> {
432 DOMStoreThreePhaseCommitCohort mockCohort = mock(DOMStoreThreePhaseCommitCohort.class);
433 doReturn(Futures.immediateFailedFuture(mockCommitEx)).when(mockCohort).canCommit();
434 doReturn(Futures.immediateFuture(null)).when(mockCohort).abort();
436 doAnswer(notused -> {
437 DOMStoreWriteTransaction mockWriteTx = mock(DOMStoreReadWriteTransaction .class);
438 doNothing().when(mockWriteTx).write(any(), any());
439 doNothing().when(mockWriteTx).merge(any(), any());
440 doNothing().when(mockWriteTx).delete(any());
441 doReturn(mockCohort).when(mockWriteTx).ready();
443 }).when(mockTxChain).newReadWriteTransaction();
446 }).doAnswer(invocation -> realOperStore.createTransactionChain()).when(spiedOperStore).createTransactionChain();
448 int timerInterval = 1;
449 try (StateProviderImpl stateProvider = new StateProviderImpl(getDataBroker(), timerInterval, tableTypeRegistry,
450 stateCollector, "global-bgp", mockScheduler)) {
451 stateProvider.init();
453 ArgumentCaptor<Runnable> timerTask = ArgumentCaptor.forClass(Runnable.class);
454 verify(mockScheduler).scheduleAtFixedRate(timerTask.capture(), eq(0L), eq((long)timerInterval),
455 eq(TimeUnit.SECONDS));
457 timerTask.getValue().run();
459 String lastError = RememberingLogger.getLastErrorThrowable().orElseThrow(
460 () -> new AssertionError("Expected logged ERROR")).toString();
461 assertTrue("Last logged ERROR didn't contain expected string: " + lastError,
462 lastError.contains(mockCommitEx.getMessage()));
464 RememberingLogger.resetLastError();
466 timerTask.getValue().run();
468 ImmutableList<LogCapture> loggedErrors = RememberingLogger.getErrorLogCaptures();
469 assertTrue("Expected no logged ERRORs: " + loggedErrors, loggedErrors.isEmpty());
471 verify(spiedOperStore, times(2)).createTransactionChain();
475 private static BgpNeighborStateAugmentation buildBgpNeighborStateAugmentation() {
476 final BgpNeighborStateAugmentation augmentation = new BgpNeighborStateAugmentationBuilder()
477 .setMessages(new MessagesBuilder().setReceived(new ReceivedBuilder()
478 .setNOTIFICATION(Uint64.ONE).setUPDATE(Uint64.ONE).build())
479 .setSent(new SentBuilder().setNOTIFICATION(Uint64.ONE).setUPDATE(Uint64.ONE).build())
484 private static AfiSafis buildAfiSafis() {
485 final NeighborAfiSafiStateAugmentationBuilder neighborAfiSafiStateAugmentation =
486 new NeighborAfiSafiStateAugmentationBuilder()
488 .setPrefixes(new PrefixesBuilder()
490 .setReceived(Uint32.TWO)
491 .setInstalled(Uint32.ONE)
493 final AfiSafi afiSafi = new AfiSafiBuilder()
494 .setAfiSafiName(IPV4UNICAST.class)
495 .setGracefulRestart(new GracefulRestartBuilder().setState(new StateBuilder().setEnabled(false)
496 .addAugmentation(NeighborAfiSafiGracefulRestartStateAugmentation.class,
497 new NeighborAfiSafiGracefulRestartStateAugmentationBuilder()
500 .setLlStaleTimer(Uint32.valueOf(60))
501 .setLlAdvertised(true)
505 .setState(new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol.rev151009.bgp
506 .common.afi.safi.list.afi.safi.StateBuilder().setEnabled(false).addAugmentation(
507 NeighborAfiSafiStateAugmentation.class, neighborAfiSafiStateAugmentation.build())
511 return new AfiSafisBuilder().setAfiSafi(Collections.singletonList(afiSafi)).build();
514 private static ErrorHandling buildErrorHandling() {
515 final ErrorHandling errorHandling = new ErrorHandlingBuilder().setState(
516 new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.error
517 .handling.StateBuilder().setTreatAsWithdraw(false)
518 .addAugmentation(NeighborErrorHandlingStateAugmentation.class,
519 new NeighborErrorHandlingStateAugmentationBuilder()
520 .setErroneousUpdateMessages(Uint32.ONE).build()).build()).build();
521 return errorHandling;
524 private static Timers buildTimers() {
525 final Timers timers = new TimersBuilder().setState(new org.opendaylight.yang.gen.v1.http.openconfig.net.yang
526 .bgp.rev151009.bgp.neighbor.group.timers.StateBuilder()
527 .setConnectRetry(BigDecimal.valueOf(30))
528 .setHoldTime(BigDecimal.valueOf(90))
529 .setKeepaliveInterval(BigDecimal.valueOf(30))
530 .setMinimumAdvertisementInterval(BigDecimal.valueOf(30))
531 .addAugmentation(NeighborTimersStateAugmentation.class, new NeighborTimersStateAugmentationBuilder()
532 .setNegotiatedHoldTime(BigDecimal.TEN).setUptime(new Timeticks(Uint32.ONE)).build())
537 private Transport buildTransport() {
538 final Transport transport = new TransportBuilder().setState(new org.opendaylight.yang.gen.v1.http.openconfig
539 .net.yang.bgp.rev151009.bgp.neighbor.group.transport.StateBuilder()
540 .setMtuDiscovery(false)
541 .setPassiveMode(false)
542 .addAugmentation(NeighborTransportStateAugmentation.class,
543 new NeighborTransportStateAugmentationBuilder().setLocalPort(this.localPort)
544 .setRemotePort(this.remotePort)
545 .setRemoteAddress(this.neighborAddress).build())
550 private GracefulRestart buildGracefulRestart() {
551 final NeighborGracefulRestartStateAugmentationBuilder gracefulAugmentation
552 = new NeighborGracefulRestartStateAugmentationBuilder()
553 .setPeerRestarting(false)
554 .setLocalRestarting(false)
555 .setPeerRestartTime(Uint16.ZERO)
556 .setLocalRestarting(true)
557 .setPeerRestarting(true)
558 .setPeerRestartTime(this.restartTime)
559 .setMode(BgpAfiSafiGracefulRestartState.Mode.BILATERAL);
560 final GracefulRestart gracefulRestart = new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp
561 .rev151009.bgp.graceful.restart.GracefulRestartBuilder().setState(new org.opendaylight.yang.gen.v1.http
562 .openconfig.net.yang.bgp.rev151009.bgp.graceful.restart.graceful.restart.StateBuilder()
563 .addAugmentation(NeighborGracefulRestartStateAugmentation.class,
564 gracefulAugmentation.build()).build()).build();
565 return gracefulRestart;
568 private Global buildGlobalExpected(final long prefixesAndPaths) {
569 return new GlobalBuilder()
570 .setState(new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.global.base
572 .setRouterId(new Ipv4Address(this.bgpId.getValue()))
573 .setTotalPrefixes(Uint32.valueOf(prefixesAndPaths))
574 .setTotalPaths(Uint32.valueOf(prefixesAndPaths))
577 .setAfiSafis(new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.rev151009.bgp.global.base
579 .setAfiSafi(Collections.singletonList(new AfiSafiBuilder()
580 .setAfiSafiName(IPV4UNICAST.class)
581 .setState(new org.opendaylight.yang.gen.v1.http.openconfig.net.yang.bgp.multiprotocol
582 .rev151009.bgp.common.afi.safi.list.afi.safi.StateBuilder()
584 .addAugmentation(GlobalAfiSafiStateAugmentation.class,
585 new GlobalAfiSafiStateAugmentationBuilder()
586 .setTotalPaths(Uint32.valueOf(prefixesAndPaths))
587 .setTotalPrefixes(Uint32.valueOf(prefixesAndPaths))
595 private static PeerGroup buildGroupExpected() {
596 return new PeerGroupBuilder().setPeerGroupName("test-group").setState(new org.opendaylight.yang.gen.v1.http
597 .openconfig.net.yang.bgp.rev151009.bgp.neighbor.group.StateBuilder()
598 .setSendCommunity(CommunityType.NONE)
599 .setRouteFlapDamping(false)
600 .addAugmentation(PeerGroupStateAugmentation.class, new PeerGroupStateAugmentationBuilder()
601 .setTotalPaths(Uint32.ONE)
602 .setTotalPrefixes(Uint32.ONE)