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