7f8fd961b71e6c311a637a18af6b77a137878cbd
[bgpcep.git] / bgp / rib-spi / src / test / java / org / opendaylight / protocol / bgp / rib / spi / MultiPathAbstractRIBSupportTest.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.rib.spi;
10
11 import static junit.framework.TestCase.assertFalse;
12 import static org.junit.Assert.assertEquals;
13 import static org.junit.Assert.assertTrue;
14 import static org.mockito.Matchers.any;
15 import static org.mockito.Mockito.doAnswer;
16 import static org.mockito.Mockito.doReturn;
17
18 import com.google.common.base.Optional;
19 import com.google.common.collect.ImmutableMap;
20 import java.util.Collection;
21 import java.util.Collections;
22 import java.util.HashMap;
23 import java.util.HashSet;
24 import java.util.Map;
25 import org.junit.Assert;
26 import org.junit.Before;
27 import org.junit.Test;
28 import org.mockito.Mockito;
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.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev171207.ipv4.routes.ipv4.routes.Ipv4Prefixes;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev171207.ipv4.routes.ipv4.routes.Ipv4Route;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev171207.ipv4.routes.ipv4.routes.Ipv4Routes;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev171207.ipv4.routes.ipv4.routes.Ipv4RoutesCase;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev171207.ipv4.routes.ipv4.routes.MultiPathAbstractTest;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.UpdateBuilder;
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.AttributesBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.Attributes1;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.Attributes1Builder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.Attributes2;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.Attributes2Builder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.destination.DestinationType;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.MpReachNlri;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.MpReachNlriBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.MpUnreachNlri;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.MpUnreachNlriBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.mp.reach.nlri.AdvertizedRoutes;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.mp.unreach.nlri.WithdrawnRoutes;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.BgpRib;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.bgp.rib.rib.LocRib;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.Tables;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.TablesKey;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.tables.Routes;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv4NextHopCase;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv4NextHopCaseBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.ipv4.next.hop._case.Ipv4NextHopBuilder;
64 import org.opendaylight.yangtools.yang.common.QName;
65 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
66 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
67 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
68 import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
69 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
70 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
71 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
72 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
73 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
74 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
75 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
76 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeSchemaAwareBuilder;
77 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafNodeBuilder;
78
79 public class MultiPathAbstractRIBSupportTest {
80     private static final long PATH_ID = 0;
81     private static final String ROUTE_KEY = "prefix";
82     private static final String PREFIX = "1.2.3.4/32";
83     private static final QName PATH_ID_QNAME = QName.create(Ipv4Route.QNAME, "path-id").intern();
84     private static final QName PREFIX_QNAME = QName.create(Ipv4Route.QNAME, ROUTE_KEY).intern();
85     private static final NodeIdentifierWithPredicates PREFIX_NII = new NodeIdentifierWithPredicates(Ipv4Route.QNAME,
86         ImmutableMap.of(QName.create(Ipv4Route.QNAME, ROUTE_KEY).intern(), PREFIX));
87     private static final MultiPathAbstractTest MULTI_PATH_ABSTRACT_TEST = new MultiPathAbstractTest();
88     private static final TablesKey TABLES_KEY = new TablesKey(Ipv4AddressFamily.class,
89             UnicastSubsequentAddressFamily.class);
90     private static final YangInstanceIdentifier LOC_RIB_TARGET = YangInstanceIdentifier
91             .create(YangInstanceIdentifier.of(BgpRib.QNAME)
92         .node(LocRib.QNAME).node(Tables.QNAME).node(RibSupportUtils.toYangTablesKey(TABLES_KEY)).getPathArguments());
93     private static final NodeIdentifier ROUTES_IDENTIFIER = new NodeIdentifier(Routes.QNAME);
94     private static final NodeIdentifier IPV4_ROUTES_IDENTIFIER = new NodeIdentifier(Ipv4Routes.QNAME);
95     private DataTreeCandidateNode emptyTree;
96     private DataTreeCandidateNode emptySubTree;
97     private DataTreeCandidateNode subTree;
98     private DOMDataWriteTransaction tx;
99     private ContainerNode nlri;
100     private Map<YangInstanceIdentifier, NormalizedNode<?, ?>> routes;
101     private ContainerNode attributes;
102     private MapEntryNode mapEntryNode;
103
104     @Before
105     public void setUp() {
106         this.routes = new HashMap<>();
107         MockitoAnnotations.initMocks(this);
108         this.emptyTree = Mockito.mock(DataTreeCandidateNode.class);
109         this.emptySubTree = Mockito.mock(DataTreeCandidateNode.class);
110         this.subTree = Mockito.mock(DataTreeCandidateNode.class);
111         final DataTreeCandidateNode emptyNode = Mockito.mock(DataTreeCandidateNode.class);
112         final DataTreeCandidateNode node = Mockito.mock(DataTreeCandidateNode.class);
113         doReturn(null).when(this.emptyTree).getModifiedChild(IPV4_ROUTES_IDENTIFIER);
114
115         doReturn(emptyNode).when(this.emptySubTree).getModifiedChild(IPV4_ROUTES_IDENTIFIER);
116         doReturn(null).when(emptyNode).getModifiedChild(new NodeIdentifier(Ipv4Route.QNAME));
117
118         doReturn(node).when(this.subTree).getModifiedChild(IPV4_ROUTES_IDENTIFIER);
119         doReturn(node).when(node).getModifiedChild(new NodeIdentifier(Ipv4Route.QNAME));
120         final Collection<DataTreeCandidateNode> emptyCollection = new HashSet<>();
121         doReturn(emptyCollection).when(node).getChildNodes();
122
123         this.tx = Mockito.mock(DOMDataWriteTransaction.class);
124         this.nlri = Mockito.mock(ContainerNode.class);
125         this.attributes = ImmutableContainerNodeBuilder.create()
126                 .withNodeIdentifier(new NodeIdentifier(QName.create(Ipv4Routes.QNAME, Attributes.QNAME
127             .getLocalName().intern()))).build();
128         final ContainerNode destination = Mockito.mock(ContainerNode.class);
129         final ContainerNode route = Mockito.mock(ContainerNode.class);
130         final Optional<?> optional = Mockito.mock(Optional.class);
131         final Optional<?> destinationOptional = Mockito.mock(Optional.class);
132         final Optional<?> destinationsOptional = Mockito.mock(Optional.class);
133         final ChoiceNode destinations = Mockito.mock(ChoiceNode.class);
134
135         doReturn(optional).when(this.nlri).getChild(new NodeIdentifier(WithdrawnRoutes.QNAME));
136         doReturn(optional).when(this.nlri).getChild(new NodeIdentifier(AdvertizedRoutes.QNAME));
137         doReturn(true).when(optional).isPresent();
138         doReturn(destination).when(optional).get();
139         doReturn(destinationOptional).when(destination).getChild(new NodeIdentifier(DestinationType.QNAME));
140         doReturn(true).when(destinationOptional).isPresent();
141         doReturn(destinations).when(destinationOptional).get();
142         doReturn(destinationsOptional).when(destinations).getChild(new NodeIdentifier(Ipv4Prefixes.QNAME));
143         doReturn(true).when(destinationsOptional).isPresent();
144         doReturn(route).when(destinationsOptional).get();
145         doReturn(emptyCollection).when(route).getValue();
146
147         doAnswer(invocation -> {
148             final Object[] args = invocation.getArguments();
149             MultiPathAbstractRIBSupportTest.this.routes.remove(args[1]);
150             return args[1];
151         }).when(this.tx).delete(Mockito.eq(LogicalDatastoreType.OPERATIONAL), any(YangInstanceIdentifier.class));
152         doAnswer(invocation -> {
153             final Object[] args = invocation.getArguments();
154             final NormalizedNode<?, ?> node1 = (NormalizedNode<?, ?>) args[2];
155             MultiPathAbstractRIBSupportTest.this.routes.put((YangInstanceIdentifier) args[1], node1);
156             return args[1];
157         }).when(this.tx).put(Mockito.eq(LogicalDatastoreType.OPERATIONAL), any(YangInstanceIdentifier.class),
158                 any(NormalizedNode.class));
159
160         this.mapEntryNode = Mockito.mock(MapEntryNode.class);
161     }
162
163     @Test
164     public void pathIdQName() {
165         final MultiPathAbstractTest multiPath = MULTI_PATH_ABSTRACT_TEST;
166         assertEquals(PATH_ID_QNAME, multiPath.pathIdQName());
167     }
168
169     @Test
170     public void extractPathId() {
171         final NodeIdentifier nii = new NodeIdentifier(PATH_ID_QNAME);
172         final ContainerNode cont = ImmutableContainerNodeSchemaAwareBuilder.create().withNodeIdentifier(nii)
173                 .addChild(new ImmutableLeafNodeBuilder<>().withNodeIdentifier(nii).withValue(PATH_ID).build()).build();
174         assertEquals((Long) PATH_ID, MULTI_PATH_ABSTRACT_TEST.extractPathId(cont));
175     }
176
177     @Test
178     public void getRouteIdAddPath() {
179         final NodeIdentifierWithPredicates routeIdPa =
180             new NodeIdentifierWithPredicates(Ipv4Route.QNAME,
181                     ImmutableMap.of(PATH_ID_QNAME, PATH_ID, PREFIX_QNAME, PREFIX));
182         assertEquals(routeIdPa, MULTI_PATH_ABSTRACT_TEST.getRouteIdAddPath(PATH_ID, PREFIX_NII));
183
184     }
185
186     @Test
187     public void createRouteKeyPathArgument() {
188         assertEquals(PREFIX_NII, MULTI_PATH_ABSTRACT_TEST.createRouteKeyPathArgument(PREFIX_NII));
189     }
190
191     @Test
192     public void routesCaseClass() throws Exception {
193         assertEquals(Ipv4RoutesCase.class, MULTI_PATH_ABSTRACT_TEST.routesCaseClass());
194     }
195
196     @Test
197     public void routesContainerClass() throws Exception {
198         assertEquals(Ipv4Routes.class, MULTI_PATH_ABSTRACT_TEST.routesContainerClass());
199     }
200
201     @Test
202     public void routesListClass() throws Exception {
203         assertEquals(Ipv4Route.class, MULTI_PATH_ABSTRACT_TEST.routesListClass());
204     }
205
206     @Test
207     public void routeQName() throws Exception {
208         assertEquals(Ipv4Route.QNAME, MULTI_PATH_ABSTRACT_TEST.routeQName());
209     }
210
211     @Test
212     public void emptyRoutes() throws Exception {
213         final ChoiceNode emptyRoutes = Builders.choiceBuilder().withNodeIdentifier(ROUTES_IDENTIFIER)
214                 .addChild(Builders.containerBuilder().withNodeIdentifier(IPV4_ROUTES_IDENTIFIER)
215                         .withChild(ImmutableNodes.mapNodeBuilder(MULTI_PATH_ABSTRACT_TEST.routeQName())
216                                 .build()).build()).build();
217         assertEquals(emptyRoutes, MULTI_PATH_ABSTRACT_TEST.emptyRoutes());
218     }
219
220     @Test
221     public void routeNid() throws Exception {
222         assertEquals(new NodeIdentifier(Ipv4Route.QNAME), MULTI_PATH_ABSTRACT_TEST.routeNid());
223     }
224
225     @Test
226     public void getAfi() throws Exception {
227         assertEquals(Ipv4AddressFamily.class, MULTI_PATH_ABSTRACT_TEST.getAfi());
228     }
229
230     @Test
231     public void getSafi() throws Exception {
232         assertEquals(UnicastSubsequentAddressFamily.class, MULTI_PATH_ABSTRACT_TEST.getSafi());
233     }
234
235     @Test
236     public void routesContainerIdentifier() throws Exception {
237         assertEquals(IPV4_ROUTES_IDENTIFIER, MULTI_PATH_ABSTRACT_TEST.routesContainerIdentifier());
238
239     }
240
241     @Test
242     public void routeAttributesIdentifier() throws Exception {
243         assertEquals(new NodeIdentifier(QName.create(Ipv4Routes.QNAME,
244                 Attributes.QNAME.getLocalName().intern())), MULTI_PATH_ABSTRACT_TEST.routeAttributesIdentifier());
245     }
246
247     @Test
248     public void routePath() throws Exception {
249         Assert.assertEquals(LOC_RIB_TARGET.node(ROUTES_IDENTIFIER)
250                         .node(Ipv4Routes.QNAME).node(Ipv4Route.QNAME).node(PREFIX_NII),
251             MULTI_PATH_ABSTRACT_TEST.routePath(LOC_RIB_TARGET.node(Routes.QNAME), PREFIX_NII));
252     }
253
254     @Test
255     public void changedRoutes() throws Exception {
256         Assert.assertTrue(MULTI_PATH_ABSTRACT_TEST.changedRoutes(this.emptyTree).isEmpty());
257         Assert.assertTrue(MULTI_PATH_ABSTRACT_TEST.changedRoutes(this.emptySubTree).isEmpty());
258         Assert.assertNotNull(MULTI_PATH_ABSTRACT_TEST.changedRoutes(this.subTree));
259     }
260
261     @Test
262     public void putRoutes() throws Exception {
263         MULTI_PATH_ABSTRACT_TEST.putRoutes(this.tx, LOC_RIB_TARGET, this.nlri, this.attributes);
264         assertFalse(this.routes.isEmpty());
265     }
266
267     @Test
268     public void deleteRoutes() throws Exception {
269         MULTI_PATH_ABSTRACT_TEST.deleteRoutes(this.tx, LOC_RIB_TARGET, this.nlri);
270         assertTrue(this.routes.isEmpty());
271     }
272
273
274     @Test
275     public void buildUpdate() throws Exception {
276         final Ipv4NextHopCase nextHop = new Ipv4NextHopCaseBuilder().setIpv4NextHop(new Ipv4NextHopBuilder()
277                 .setGlobal(new Ipv4Address("10.0.0.2")).build()).build();
278         final Attributes attr = new AttributesBuilder().setCNextHop(nextHop).build();
279         final Collection<MapEntryNode> routes = new HashSet<>();
280
281         assertEquals(new UpdateBuilder().setAttributes(new AttributesBuilder().build()).build(),
282                 MULTI_PATH_ABSTRACT_TEST.buildUpdate(routes, routes, attr));
283
284         routes.add(this.mapEntryNode);
285         final MpReachNlri mpReach = new MpReachNlriBuilder().setAfi(Ipv4AddressFamily.class)
286                 .setSafi(UnicastSubsequentAddressFamily.class)
287                 .setCNextHop(nextHop).setAdvertizedRoutes(new AdvertizedRoutesBuilder().build()).build();
288
289         final Attributes attMpR = new AttributesBuilder().addAugmentation(Attributes1.class,
290                 new Attributes1Builder().setMpReachNlri(mpReach).build()).build();
291         assertEquals(new UpdateBuilder().setAttributes(attMpR).build(),
292                 MULTI_PATH_ABSTRACT_TEST.buildUpdate(routes, Collections.emptySet(), attr));
293
294         final MpUnreachNlri mpUnreach = new MpUnreachNlriBuilder().setAfi(Ipv4AddressFamily.class)
295                 .setSafi(UnicastSubsequentAddressFamily.class)
296                 .setWithdrawnRoutes(new WithdrawnRoutesBuilder().build()).build();
297
298         final Attributes attMpU = new AttributesBuilder().addAugmentation(Attributes2.class,
299                 new Attributes2Builder().setMpUnreachNlri(mpUnreach).build()).build();
300         assertEquals(new UpdateBuilder().setAttributes(attMpU).build(),
301                 MULTI_PATH_ABSTRACT_TEST.buildUpdate(Collections.emptySet(), routes, attr));
302     }
303 }