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