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