Fix findbug and checkstyle issues
[bgpcep.git] / bgp / path-selection-mode / src / test / java / org / opendaylight / protocol / bgp / mode / impl / AbstractRouteEntryTest.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.mode.impl;
10
11 import static org.mockito.Matchers.any;
12 import static org.mockito.Matchers.eq;
13 import static org.mockito.Mockito.doAnswer;
14 import static org.mockito.Mockito.doReturn;
15 import static org.opendaylight.protocol.bgp.mode.impl.base.BasePathSelectorTest.ATTRS_EXTENSION_Q;
16 import static org.opendaylight.protocol.bgp.mode.impl.base.BasePathSelectorTest.SEGMENTS_NID;
17
18 import com.google.common.collect.ImmutableMap;
19 import com.google.common.primitives.UnsignedInteger;
20 import java.util.ArrayList;
21 import java.util.HashMap;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.Map.Entry;
25 import java.util.function.BiConsumer;
26 import java.util.function.Function;
27 import java.util.stream.Collectors;
28 import org.mockito.Mock;
29 import org.mockito.MockitoAnnotations;
30 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
31 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
32 import org.opendaylight.protocol.bgp.rib.spi.ExportPolicyPeerTracker;
33 import org.opendaylight.protocol.bgp.rib.spi.PeerExportGroup;
34 import org.opendaylight.protocol.bgp.rib.spi.PeerExportGroup.PeerExporTuple;
35 import org.opendaylight.protocol.bgp.rib.spi.RIBSupport;
36 import org.opendaylight.protocol.bgp.rib.spi.RibSupportUtils;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev171207.ipv4.routes.Ipv4Routes;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev171207.ipv4.routes.ipv4.routes.Ipv4Route;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.Attributes;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.attributes.AsPath;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.attributes.AtomicAggregate;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.attributes.Origin;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.BgpRib;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.PeerId;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.PeerRole;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.bgp.rib.rib.LocRib;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.bgp.rib.rib.peer.AdjRibOut;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.Tables;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.TablesKey;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.tables.Routes;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily;
53 import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
54 import org.opendaylight.yangtools.yang.common.QName;
55 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
56 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
57 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
58 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
59 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
60 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
61 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
62 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
63
64 public abstract class AbstractRouteEntryTest {
65     protected static final long REMOTE_PATH_ID = 1;
66     protected static final PeerId PEER_ID = new PeerId("bgp://42.42.42.42");
67     protected static final YangInstanceIdentifier PEER_YII2 = YangInstanceIdentifier
68             .of(QName.create("urn:opendaylight:params:xml:ns:yang:bgp-inet:test",
69                     "2015-03-05", "peer2"));
70     protected static final long AS = 64444;
71     protected static final UnsignedInteger ROUTER_ID = UnsignedInteger.ONE;
72     protected static final TablesKey TABLES_KEY = new TablesKey(Ipv4AddressFamily.class,
73             UnicastSubsequentAddressFamily.class);
74     protected static final YangInstanceIdentifier LOC_RIB_TARGET =
75             YangInstanceIdentifier.create(YangInstanceIdentifier.of(BgpRib.QNAME).node(LocRib.QNAME)
76                     .node(Tables.QNAME).node(RibSupportUtils.toYangTablesKey(TABLES_KEY)).getPathArguments());
77     private static final long PATH_ID = 1;
78     private static final PeerId PEER_ID2 = new PeerId("bgp://43.43.43.43");
79     private static final String PREFIX = "1.2.3.4/32";
80     private static final String PREFIX2 = "2.2.2.2/32";
81     private static final YangInstanceIdentifier PEER_YII
82             = YangInstanceIdentifier.of(QName.create("urn:opendaylight:params:xml:ns:yang:bgp-inet:test",
83             "2015-03-05", "peer1"));
84     private static final NodeIdentifier ROUTES_IDENTIFIER = new NodeIdentifier(Routes.QNAME);
85     private static final NodeIdentifier ORIGIN_NID = new NodeIdentifier(QName.create(ATTRS_EXTENSION_Q,
86             Origin.QNAME.getLocalName()).intern());
87     private static final NodeIdentifier ORIGIN_VALUE_NID = new NodeIdentifier(QName.create(ATTRS_EXTENSION_Q,
88             "value").intern());
89     private static final NodeIdentifier AS_PATH_NID = new NodeIdentifier(QName.create(ATTRS_EXTENSION_Q,
90             AsPath.QNAME.getLocalName()).intern());
91     private static final NodeIdentifier ATOMIC_NID = new NodeIdentifier(QName.create(ATTRS_EXTENSION_Q,
92             AtomicAggregate.QNAME.getLocalName()));
93     private static final QName Q_NAME = BindingReflections.findQName(Ipv4Routes.class).intern();
94     private static final NodeIdentifier ROUTE_ATTRIBUTES_IDENTIFIER
95             = new NodeIdentifier(QName.create(Q_NAME, Attributes.QNAME.getLocalName().intern()));
96     private static final QName PREFIX_QNAME
97             = QName.create(Ipv4Route.QNAME, "prefix").intern();
98     protected static final NodeIdentifierWithPredicates ROUTE_ID_PA
99             = new NodeIdentifierWithPredicates(Ipv4Route.QNAME, ImmutableMap.of(PREFIX_QNAME, PREFIX));
100     private static final QName PATHID_QNAME = QName.create(Ipv4Route.QNAME, "path-id").intern();
101     protected static final NodeIdentifierWithPredicates ROUTE_ID_PA_ADD_PATH
102             = new NodeIdentifierWithPredicates(Ipv4Route.QNAME,
103             ImmutableMap.of(PATHID_QNAME, PATH_ID, PREFIX_QNAME, PREFIX2));
104     @Mock
105     protected RIBSupport ribSupport;
106     @Mock
107     protected DOMDataWriteTransaction tx;
108     @Mock
109     protected ExportPolicyPeerTracker peerPT;
110     @Mock
111     protected PeerExportGroup peg;
112     protected List<YangInstanceIdentifier> yiichanges;
113     protected NormalizedNode<?, ?> attributes;
114     protected YangInstanceIdentifier routePaYii;
115     protected YangInstanceIdentifier routePaAddPathYii;
116     protected YangInstanceIdentifier routeRiboutYii;
117     protected YangInstanceIdentifier routeAddRiboutYii;
118     protected YangInstanceIdentifier routeRiboutAttYii;
119     protected YangInstanceIdentifier routeAddRiboutAttYii;
120     protected YangInstanceIdentifier routeRiboutAttYiiPeer2;
121     protected YangInstanceIdentifier routeRiboutYiiPeer2;
122     protected YangInstanceIdentifier routeAddRiboutYiiPeer2;
123     @Mock
124     private PeerExportGroup pegNot;
125     private YangInstanceIdentifier locRibTargetYii;
126     private YangInstanceIdentifier locRibOutTargetYii;
127     private YangInstanceIdentifier locRibOutTargetYiiPeer2;
128
129     protected void setUp() {
130         MockitoAnnotations.initMocks(this);
131         this.yiichanges = new ArrayList<>();
132         this.attributes = createAttr();
133         this.locRibTargetYii = LOC_RIB_TARGET.node(ROUTES_IDENTIFIER);
134         this.locRibOutTargetYii = PEER_YII.node(AdjRibOut.QNAME).node(Tables.QNAME)
135                 .node(RibSupportUtils.toYangTablesKey(TABLES_KEY)).node(ROUTES_IDENTIFIER);
136         this.routePaYii = this.locRibTargetYii.node(ROUTE_ID_PA);
137         this.routePaAddPathYii = this.locRibTargetYii.node(ROUTE_ID_PA_ADD_PATH);
138         this.routeRiboutYii = this.locRibOutTargetYii.node(ROUTE_ID_PA);
139         this.routeAddRiboutYii = this.locRibOutTargetYii.node(ROUTE_ID_PA_ADD_PATH);
140         this.routeRiboutAttYii = this.locRibOutTargetYii.node(ROUTE_ID_PA).node(ATTRS_EXTENSION_Q);
141         this.routeAddRiboutAttYii = this.locRibOutTargetYii.node(ROUTE_ID_PA_ADD_PATH).node(ATTRS_EXTENSION_Q);
142         this.locRibOutTargetYiiPeer2 = PEER_YII2.node(AdjRibOut.QNAME).node(Tables.QNAME)
143                 .node(RibSupportUtils.toYangTablesKey(TABLES_KEY)).node(ROUTES_IDENTIFIER);
144         this.routeRiboutYiiPeer2 = this.locRibOutTargetYiiPeer2.node(ROUTE_ID_PA);
145         this.routeRiboutAttYiiPeer2 = this.locRibOutTargetYiiPeer2.node(ROUTE_ID_PA).node(ATTRS_EXTENSION_Q);
146         this.routeAddRiboutYiiPeer2 = this.locRibOutTargetYiiPeer2.node(ROUTE_ID_PA_ADD_PATH);
147         mockRibSupport();
148         mockExportPolicies();
149         mockExportGroup();
150         mockTransactionChain();
151     }
152
153     private void mockTransactionChain() {
154         doAnswer(invocation -> {
155             final Object[] args = invocation.getArguments();
156             this.yiichanges.add((YangInstanceIdentifier) args[1]);
157             return args[1];
158         }).when(this.tx)
159                 .put(any(LogicalDatastoreType.class), any(YangInstanceIdentifier.class), any(NormalizedNode.class));
160
161         doAnswer(invocation -> {
162             final Object[] args = invocation.getArguments();
163             if (this.routePaYii.equals(args[1])) {
164                 this.yiichanges.remove(this.routePaYii);
165             } else if (this.routePaAddPathYii.equals(args[1])) {
166                 this.yiichanges.remove(this.routePaAddPathYii);
167             } else if (this.routeRiboutYii.equals(args[1])) {
168                 this.yiichanges.remove(this.routeRiboutYii);
169                 this.yiichanges.remove(this.routeAddRiboutAttYii);
170             } else if (this.routeAddRiboutYii.equals(args[1])) {
171                 this.yiichanges.remove(this.routeAddRiboutYii);
172                 this.yiichanges.remove(this.routeAddRiboutAttYii);
173             }
174             return args[1];
175         }).when(this.tx).delete(any(LogicalDatastoreType.class), any(YangInstanceIdentifier.class));
176     }
177
178     private void mockExportGroup() {
179         doReturn(this.attributes).when(this.peg).effectiveAttributes(any(PeerRole.class), any(ContainerNode.class));
180         doReturn(null).when(this.pegNot).effectiveAttributes(any(PeerRole.class), any(ContainerNode.class));
181
182         final Map<PeerId, PeerExportGroup.PeerExporTuple> peers = new HashMap<>();
183         doAnswer(invocation -> {
184             final BiConsumer<PeerId, YangInstanceIdentifier> action = (BiConsumer) invocation.getArguments()[0];
185             for (final Entry<PeerId, PeerExporTuple> pid : peers.entrySet()) {
186                 action.accept(pid.getKey(), pid.getValue().getYii());
187             }
188             return null;
189         }).when(this.pegNot).forEach(any());
190         doReturn(Boolean.TRUE).when(this.pegNot).containsPeer(any(PeerId.class));
191
192         peers.put(PEER_ID, new PeerExportGroup.PeerExporTuple(PEER_YII, PeerRole.Ibgp));
193         peers.put(PEER_ID2, new PeerExportGroup.PeerExporTuple(PEER_YII2, PeerRole.Ibgp));
194         doAnswer(invocation -> {
195             final BiConsumer<PeerId, YangInstanceIdentifier> action = (BiConsumer) invocation.getArguments()[0];
196             for (final Entry<PeerId, PeerExporTuple> pid : peers.entrySet()) {
197                 action.accept(pid.getKey(), pid.getValue().getYii());
198             }
199             return null;
200         }).when(this.peg).forEach(any());
201     }
202
203     private void mockExportPolicies() {
204         doReturn(Boolean.TRUE).when(this.peerPT).isTableStructureInitialized(any(PeerId.class));
205         doReturn(Boolean.TRUE).when(this.peerPT).isTableSupported(PEER_ID);
206         doReturn(Boolean.FALSE).when(this.peerPT).isTableSupported(PEER_ID2);
207         doAnswer(invocation -> {
208             final Object[] args = invocation.getArguments();
209             if (PeerRole.Ibgp.equals(args[0])) {
210                 return this.peg;
211             } else if (PeerRole.Ebgp.equals(args[0])) {
212                 return this.pegNot;
213             } else {
214                 return null;
215             }
216         }).when(this.peerPT).getPeerGroup(any(PeerRole.class));
217
218         doReturn(Boolean.TRUE).when(this.peerPT).isAddPathSupportedByPeer(PEER_ID);
219         doReturn(Boolean.FALSE).when(this.peerPT).isAddPathSupportedByPeer(PEER_ID2);
220     }
221
222     private void mockRibSupport() {
223         doReturn(ROUTE_ATTRIBUTES_IDENTIFIER).when(this.ribSupport).routeAttributesIdentifier();
224         doReturn(ROUTE_ID_PA_ADD_PATH).when(this.ribSupport)
225                 .getRouteIdAddPath(any(Long.class), eq(ROUTE_ID_PA_ADD_PATH));
226         doReturn(null).when(this.ribSupport).getRouteIdAddPath(any(Long.class), eq(ROUTE_ID_PA));
227         doAnswer(invocation -> {
228             final Object[] args = invocation.getArguments();
229             final YangInstanceIdentifier yii = (YangInstanceIdentifier) args[0];
230             final PathArgument paa = (PathArgument) args[1];
231
232             if (ROUTE_ID_PA.equals(paa)) {
233                 if (yii.equals(this.locRibTargetYii)) {
234                     return this.routePaYii;
235                 } else if (yii.equals(this.locRibOutTargetYii)) {
236                     return this.routeRiboutYii;
237                 } else if (yii.equals(this.locRibOutTargetYiiPeer2)) {
238                     return this.routeRiboutYiiPeer2;
239                 }
240             } else if (ROUTE_ID_PA_ADD_PATH.equals(paa)) {
241                 if (yii.equals(this.locRibTargetYii)) {
242                     return this.routePaAddPathYii;
243                 } else if (yii.equals(this.locRibOutTargetYii)) {
244                     return this.routeAddRiboutYii;
245                 } else if (yii.equals(this.locRibOutTargetYiiPeer2)) {
246                     return this.routeAddRiboutYiiPeer2;
247                 }
248             }
249             return null;
250         }).when(this.ribSupport).routePath(any(YangInstanceIdentifier.class), any(PathArgument.class));
251     }
252
253     private static NormalizedNode<?, ?> createAttr() {
254         final ContainerNode attributes = Builders.containerBuilder()
255                 .withNodeIdentifier(new NodeIdentifier(ATTRS_EXTENSION_Q))
256             .addChild(Builders.containerBuilder().withNodeIdentifier(ORIGIN_NID)
257                 .addChild(Builders.leafBuilder().withNodeIdentifier(ORIGIN_VALUE_NID)
258                         .withValue("igp").build()).build())
259             .addChild(Builders.containerBuilder().withNodeIdentifier(AS_PATH_NID)
260                 .addChild(Builders.unkeyedListBuilder().withNodeIdentifier(SEGMENTS_NID).build()).build())
261             .addChild(Builders.containerBuilder().withNodeIdentifier(ATOMIC_NID).build()).build();
262         return ImmutableContainerNodeBuilder.create().withNodeIdentifier(ROUTE_ATTRIBUTES_IDENTIFIER)
263             .withChild(attributes).build();
264     }
265
266     protected Map<YangInstanceIdentifier, Long> collectInfo() {
267         return this.yiichanges.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
268     }
269 }