2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
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
9 package org.opendaylight.protocol.bgp.rib.spi;
11 import static junit.framework.TestCase.assertFalse;
12 import static org.junit.Assert.assertEquals;
13 import static org.junit.Assert.assertNotNull;
14 import static org.junit.Assert.assertTrue;
15 import static org.mockito.ArgumentMatchers.any;
16 import static org.mockito.Mockito.doAnswer;
17 import static org.mockito.Mockito.doReturn;
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;
25 import java.util.Optional;
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.binding.impl.BindingToNormalizedNodeCodec;
31 import org.opendaylight.controller.md.sal.binding.test.AbstractConcurrentDataBrokerTest;
32 import org.opendaylight.controller.md.sal.binding.test.AbstractDataBrokerTestCustomizer;
33 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
34 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.UpdateBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.path.attributes.Attributes;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.path.attributes.AttributesBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes1;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes1Builder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes2;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes2Builder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.destination.DestinationType;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.MpReachNlri;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.MpReachNlriBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.MpUnreachNlri;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.MpUnreachNlriBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.reach.nlri.AdvertizedRoutes;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.unreach.nlri.WithdrawnRoutes;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.BgpRib;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.bgp.rib.rib.LocRib;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.Tables;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.TablesKey;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.tables.Routes;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.test.rev180515.Ipv4Prefixes;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.test.rev180515.bgp.rib.rib.loc.rib.tables.routes.Ipv4RoutesCase;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.test.rev180515.ipv4.routes.Ipv4Routes;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.test.rev180515.ipv4.routes.ipv4.routes.Ipv4Route;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.Ipv4AddressFamily;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.UnicastSubsequentAddressFamily;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.next.hop.c.next.hop.Ipv4NextHopCase;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.next.hop.c.next.hop.Ipv4NextHopCaseBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.next.hop.c.next.hop.ipv4.next.hop._case.Ipv4NextHopBuilder;
66 import org.opendaylight.yangtools.yang.common.QName;
67 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
68 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
69 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
70 import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
71 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
72 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
73 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
74 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
75 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
77 public class RIBSupportTest extends AbstractConcurrentDataBrokerTest {
78 private static final String ROUTE_KEY = "prefix";
79 private static final String PREFIX = "1.2.3.4/32";
80 private static final QName PATH_ID_QNAME = QName.create(Ipv4Route.QNAME, "path-id").intern();
81 private static final NodeIdentifierWithPredicates PREFIX_NII = new NodeIdentifierWithPredicates(Ipv4Route.QNAME,
82 ImmutableMap.of(QName.create(Ipv4Route.QNAME, ROUTE_KEY).intern(), PREFIX));
83 private RIBSupportTestImp ribSupportTestImp;
84 private static final TablesKey TABLES_KEY = new TablesKey(Ipv4AddressFamily.class,
85 UnicastSubsequentAddressFamily.class);
86 private static final YangInstanceIdentifier LOC_RIB_TARGET = YangInstanceIdentifier
87 .create(YangInstanceIdentifier.of(BgpRib.QNAME)
88 .node(LocRib.QNAME).node(Tables.QNAME).node(RibSupportUtils.toYangTablesKey(TABLES_KEY)).getPathArguments());
89 private static final NodeIdentifier ROUTES_IDENTIFIER = new NodeIdentifier(Routes.QNAME);
90 private static final NodeIdentifier IPV4_ROUTES_IDENTIFIER = new NodeIdentifier(Ipv4Routes.QNAME);
91 private DataTreeCandidateNode emptyTree;
92 private DataTreeCandidateNode emptySubTree;
93 private DataTreeCandidateNode subTree;
94 private DOMDataWriteTransaction tx;
95 private ContainerNode nlri;
96 private final Map<YangInstanceIdentifier, NormalizedNode<?, ?>> routesMap = new HashMap<>();
97 private ContainerNode attributes;
98 private MapEntryNode mapEntryNode;
99 private BindingToNormalizedNodeCodec mappingService;
102 public void setUp() throws Exception {
104 MockitoAnnotations.initMocks(this);
105 this.ribSupportTestImp = new RIBSupportTestImp(this.mappingService);
106 this.emptyTree = Mockito.mock(DataTreeCandidateNode.class);
107 this.emptySubTree = Mockito.mock(DataTreeCandidateNode.class);
108 this.subTree = Mockito.mock(DataTreeCandidateNode.class);
109 final DataTreeCandidateNode emptyNode = Mockito.mock(DataTreeCandidateNode.class);
110 final DataTreeCandidateNode node = Mockito.mock(DataTreeCandidateNode.class);
111 doReturn(Optional.empty()).when(this.emptyTree).getModifiedChild(IPV4_ROUTES_IDENTIFIER);
113 doReturn(Optional.of(emptyNode)).when(this.emptySubTree).getModifiedChild(IPV4_ROUTES_IDENTIFIER);
114 doReturn(Optional.empty()).when(emptyNode).getModifiedChild(new NodeIdentifier(Ipv4Route.QNAME));
116 doReturn(Optional.of(node)).when(this.subTree).getModifiedChild(IPV4_ROUTES_IDENTIFIER);
117 doReturn(Optional.of(node)).when(node).getModifiedChild(new NodeIdentifier(Ipv4Route.QNAME));
118 final Collection<DataTreeCandidateNode> emptyCollection = new HashSet<>();
119 doReturn(emptyCollection).when(node).getChildNodes();
121 this.tx = Mockito.mock(DOMDataWriteTransaction.class);
122 this.nlri = Mockito.mock(ContainerNode.class);
123 this.attributes = ImmutableContainerNodeBuilder.create()
124 .withNodeIdentifier(new NodeIdentifier(QName.create(Ipv4Routes.QNAME, Attributes.QNAME
125 .getLocalName().intern()))).build();
126 final ContainerNode destination = Mockito.mock(ContainerNode.class);
127 final ChoiceNode destinations = Mockito.mock(ChoiceNode.class);
128 final ContainerNode route = Mockito.mock(ContainerNode.class);
129 final Optional<?> optional = Optional.of(destination);
130 final Optional<?> destinationOptional = Optional.of(destinations);
131 final Optional<?> destinationsOptional = Optional.of(route);
133 doReturn(optional).when(this.nlri).getChild(new NodeIdentifier(WithdrawnRoutes.QNAME));
134 doReturn(optional).when(this.nlri).getChild(new NodeIdentifier(AdvertizedRoutes.QNAME));
135 doReturn(destinationOptional).when(destination).getChild(new NodeIdentifier(DestinationType.QNAME));
136 doReturn(destinationsOptional).when(destinations).getChild(new NodeIdentifier(Ipv4Prefixes.QNAME));
137 doReturn(emptyCollection).when(route).getValue();
139 doAnswer(invocation -> {
140 final Object[] args = invocation.getArguments();
141 this.routesMap.remove(args[1]);
143 }).when(this.tx).delete(Mockito.eq(LogicalDatastoreType.OPERATIONAL), any(YangInstanceIdentifier.class));
144 doAnswer(invocation -> {
145 final Object[] args = invocation.getArguments();
146 final NormalizedNode<?, ?> node1 = (NormalizedNode<?, ?>) args[2];
147 this.routesMap.put((YangInstanceIdentifier) args[1], node1);
149 }).when(this.tx).put(Mockito.eq(LogicalDatastoreType.OPERATIONAL), any(YangInstanceIdentifier.class),
150 any(NormalizedNode.class));
152 this.mapEntryNode = Mockito.mock(MapEntryNode.class);
156 protected final AbstractDataBrokerTestCustomizer createDataBrokerTestCustomizer() {
157 final AbstractDataBrokerTestCustomizer customizer = super.createDataBrokerTestCustomizer();
158 this.mappingService = customizer.getBindingToNormalized();
163 public void pathIdQName() {
164 assertEquals(PATH_ID_QNAME,this.ribSupportTestImp.pathIdQName());
168 public void routesCaseClass() {
169 assertEquals(Ipv4RoutesCase.class,this.ribSupportTestImp.routesCaseClass());
173 public void routesContainerClass() {
174 assertEquals(Ipv4Routes.class,this.ribSupportTestImp.routesContainerClass());
178 public void routesListClass() {
179 assertEquals(Ipv4Route.class,this.ribSupportTestImp.routesListClass());
183 public void routeQName() {
184 assertEquals(Ipv4Route.QNAME,this.ribSupportTestImp.routeQName());
188 public void routeNid() {
189 assertEquals(new NodeIdentifier(Ipv4Route.QNAME),this.ribSupportTestImp.routeNid());
193 public void getAfi() {
194 assertEquals(Ipv4AddressFamily.class,this.ribSupportTestImp.getAfi());
198 public void getSafi() {
199 assertEquals(UnicastSubsequentAddressFamily.class,this.ribSupportTestImp.getSafi());
203 public void routesContainerIdentifier() {
204 assertEquals(IPV4_ROUTES_IDENTIFIER,this.ribSupportTestImp.routesContainerIdentifier());
209 public void routeAttributesIdentifier() {
210 assertEquals(new NodeIdentifier(QName.create(Ipv4Routes.QNAME,
211 Attributes.QNAME.getLocalName().intern())),this.ribSupportTestImp.routeAttributesIdentifier());
215 public void routePath() {
216 assertEquals(LOC_RIB_TARGET.node(ROUTES_IDENTIFIER)
217 .node(Ipv4Routes.QNAME).node(Ipv4Route.QNAME).node(PREFIX_NII),
218 this.ribSupportTestImp.routePath(LOC_RIB_TARGET, PREFIX_NII));
222 public void changedRoutes() {
223 assertTrue(ribSupportTestImp.changedRoutes(this.emptyTree).isEmpty());
224 assertTrue(ribSupportTestImp.changedRoutes(this.emptySubTree).isEmpty());
225 assertNotNull(ribSupportTestImp.changedRoutes(this.subTree));
229 public void putRoutes() {
230 this.ribSupportTestImp.putRoutes(this.tx, LOC_RIB_TARGET, this.nlri, this.attributes);
231 assertFalse(this.routesMap.isEmpty());
235 public void deleteRoutes() {
236 this.ribSupportTestImp.deleteRoutes(this.tx, LOC_RIB_TARGET, this.nlri);
237 assertTrue(this.routesMap.isEmpty());
242 public void buildUpdate() {
243 final Ipv4NextHopCase nextHop = new Ipv4NextHopCaseBuilder().setIpv4NextHop(new Ipv4NextHopBuilder()
244 .setGlobal(new Ipv4Address("10.0.0.2")).build()).build();
245 final Attributes attr = new AttributesBuilder().setCNextHop(nextHop).build();
246 final Collection<MapEntryNode> routes = new HashSet<>();
248 assertEquals(new UpdateBuilder().setAttributes(new AttributesBuilder().build()).build(),
249 this.ribSupportTestImp.buildUpdate(routes, routes, attr));
251 routes.add(this.mapEntryNode);
252 final MpReachNlri mpReach = new MpReachNlriBuilder().setAfi(Ipv4AddressFamily.class)
253 .setSafi(UnicastSubsequentAddressFamily.class)
254 .setCNextHop(nextHop).setAdvertizedRoutes(new AdvertizedRoutesBuilder().build()).build();
256 final Attributes attMpR = new AttributesBuilder().addAugmentation(Attributes1.class,
257 new Attributes1Builder().setMpReachNlri(mpReach).build()).build();
258 assertEquals(new UpdateBuilder().setAttributes(attMpR).build(),
259 this.ribSupportTestImp.buildUpdate(routes, Collections.emptySet(), attr));
261 final MpUnreachNlri mpUnreach = new MpUnreachNlriBuilder().setAfi(Ipv4AddressFamily.class)
262 .setSafi(UnicastSubsequentAddressFamily.class)
263 .setWithdrawnRoutes(new WithdrawnRoutesBuilder().build()).build();
265 final Attributes attMpU = new AttributesBuilder().addAugmentation(Attributes2.class,
266 new Attributes2Builder().setMpUnreachNlri(mpUnreach).build()).build();
267 assertEquals(new UpdateBuilder().setAttributes(attMpU).build(),
268 this.ribSupportTestImp.buildUpdate(Collections.emptySet(), routes, attr));