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