f7c8cf33a1f5585884a7d650742a775a852c8ff5
[bgpcep.git] / bgp / rib-spi / src / test / java / org / opendaylight / protocol / bgp / rib / spi / RIBSupportTest.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.rib.spi;
9
10 import static junit.framework.TestCase.assertFalse;
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertNotNull;
13 import static org.junit.Assert.assertTrue;
14 import static org.mockito.ArgumentMatchers.any;
15 import static org.mockito.Mockito.doAnswer;
16 import static org.mockito.Mockito.doReturn;
17
18 import java.util.Collection;
19 import java.util.HashMap;
20 import java.util.HashSet;
21 import java.util.Map;
22 import java.util.Optional;
23 import java.util.Set;
24 import org.junit.Before;
25 import org.junit.Test;
26 import org.mockito.Mockito;
27 import org.mockito.MockitoAnnotations;
28 import org.opendaylight.mdsal.binding.dom.adapter.AdapterContext;
29 import org.opendaylight.mdsal.binding.dom.adapter.test.AbstractConcurrentDataBrokerTest;
30 import org.opendaylight.mdsal.binding.dom.adapter.test.AbstractDataBrokerTestCustomizer;
31 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
32 import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.UpdateBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.path.attributes.Attributes;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.path.attributes.AttributesBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.AttributesReachBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.AttributesUnreachBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.attributes.reach.MpReachNlri;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.attributes.reach.MpReachNlriBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.attributes.reach.mp.reach.nlri.AdvertizedRoutes;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.attributes.reach.mp.reach.nlri.AdvertizedRoutesBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.attributes.unreach.MpUnreachNlri;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.attributes.unreach.MpUnreachNlriBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.attributes.unreach.mp.unreach.nlri.WithdrawnRoutes;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.attributes.unreach.mp.unreach.nlri.WithdrawnRoutesBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.destination.DestinationType;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.BgpRib;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.bgp.rib.rib.LocRib;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.Tables;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.TablesKey;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.tables.Routes;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.test.rev180515.Ipv4Prefixes;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.test.rev180515.bgp.rib.rib.loc.rib.tables.routes.Ipv4RoutesCase;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.test.rev180515.ipv4.routes.Ipv4Routes;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.test.rev180515.ipv4.routes.ipv4.routes.Ipv4Route;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.Ipv4AddressFamily;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.UnicastSubsequentAddressFamily;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.next.hop.c.next.hop.Ipv4NextHopCase;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.next.hop.c.next.hop.Ipv4NextHopCaseBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.next.hop.c.next.hop.ipv4.next.hop._case.Ipv4NextHopBuilder;
62 import org.opendaylight.yangtools.yang.common.QName;
63 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
64 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
65 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
66 import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
67 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
68 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
69 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
70 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
71 import org.opendaylight.yangtools.yang.data.tree.api.DataTreeCandidateNode;
72
73 public class RIBSupportTest extends AbstractConcurrentDataBrokerTest {
74     private static final String ROUTE_KEY = "prefix";
75     private static final String PREFIX = "1.2.3.4/32";
76     private static final QName PATH_ID_QNAME = QName.create(Ipv4Route.QNAME, "path-id").intern();
77     private static final NodeIdentifierWithPredicates PREFIX_NII = NodeIdentifierWithPredicates.of(Ipv4Route.QNAME,
78         QName.create(Ipv4Route.QNAME, ROUTE_KEY).intern(), PREFIX);
79     private RIBSupportTestImp ribSupportTestImp;
80     private static final TablesKey TABLES_KEY = new TablesKey(Ipv4AddressFamily.VALUE,
81             UnicastSubsequentAddressFamily.VALUE);
82     private static final YangInstanceIdentifier LOC_RIB_TARGET = YangInstanceIdentifier
83             .create(YangInstanceIdentifier.of(BgpRib.QNAME)
84         .node(LocRib.QNAME).node(Tables.QNAME).node(RibSupportUtils.toYangTablesKey(TABLES_KEY)).getPathArguments());
85     private static final NodeIdentifier ROUTES_IDENTIFIER = new NodeIdentifier(Routes.QNAME);
86     private static final NodeIdentifier IPV4_ROUTES_IDENTIFIER = new NodeIdentifier(Ipv4Routes.QNAME);
87     private DataTreeCandidateNode emptyTree;
88     private DataTreeCandidateNode emptySubTree;
89     private DataTreeCandidateNode subTree;
90     private DOMDataTreeWriteTransaction tx;
91     private ContainerNode nlri;
92     private final Map<YangInstanceIdentifier, NormalizedNode> routesMap = new HashMap<>();
93     private ContainerNode attributes;
94     private MapEntryNode mapEntryNode;
95     private AdapterContext context;
96
97     @Before
98     public void setUp() throws Exception {
99         super.setup();
100         MockitoAnnotations.initMocks(this);
101         ribSupportTestImp = new RIBSupportTestImp(context.currentSerializer());
102         emptyTree = Mockito.mock(DataTreeCandidateNode.class);
103         emptySubTree = Mockito.mock(DataTreeCandidateNode.class);
104         subTree = Mockito.mock(DataTreeCandidateNode.class);
105         final DataTreeCandidateNode emptyNode = Mockito.mock(DataTreeCandidateNode.class);
106         final DataTreeCandidateNode node = Mockito.mock(DataTreeCandidateNode.class);
107         doReturn(Optional.empty()).when(emptyTree).getModifiedChild(IPV4_ROUTES_IDENTIFIER);
108
109         doReturn(Optional.of(emptyNode)).when(emptySubTree).getModifiedChild(IPV4_ROUTES_IDENTIFIER);
110         doReturn(Optional.empty()).when(emptyNode).getModifiedChild(new NodeIdentifier(Ipv4Route.QNAME));
111
112         doReturn(Optional.of(node)).when(subTree).getModifiedChild(IPV4_ROUTES_IDENTIFIER);
113         doReturn(Optional.of(node)).when(node).getModifiedChild(new NodeIdentifier(Ipv4Route.QNAME));
114         final Collection<DataTreeCandidateNode> emptyCollection = new HashSet<>();
115         doReturn(emptyCollection).when(node).getChildNodes();
116
117         tx = Mockito.mock(DOMDataTreeWriteTransaction.class);
118         nlri = Mockito.mock(ContainerNode.class);
119         attributes = Builders.containerBuilder()
120                 .withNodeIdentifier(new NodeIdentifier(QName.create(Ipv4Routes.QNAME, Attributes.QNAME
121                     .getLocalName().intern())))
122                 .build();
123         final ContainerNode destination = Mockito.mock(ContainerNode.class);
124         final ChoiceNode destinations = Mockito.mock(ChoiceNode.class);
125         final ContainerNode route = Mockito.mock(ContainerNode.class);
126
127         doReturn(destination).when(nlri).childByArg(new NodeIdentifier(WithdrawnRoutes.QNAME));
128         doReturn(destination).when(nlri).childByArg(new NodeIdentifier(AdvertizedRoutes.QNAME));
129         doReturn(destinations).when(destination).childByArg(new NodeIdentifier(DestinationType.QNAME));
130         doReturn(route).when(destinations).childByArg(new NodeIdentifier(Ipv4Prefixes.QNAME));
131         doReturn(emptyCollection).when(route).body();
132
133         doAnswer(invocation -> {
134             final Object[] args = invocation.getArguments();
135             routesMap.remove(args[1]);
136             return args[1];
137         }).when(tx).delete(Mockito.eq(LogicalDatastoreType.OPERATIONAL), any(YangInstanceIdentifier.class));
138         doAnswer(invocation -> {
139             final Object[] args = invocation.getArguments();
140             final NormalizedNode node1 = (NormalizedNode) args[2];
141             routesMap.put((YangInstanceIdentifier) args[1], node1);
142             return args[1];
143         }).when(tx).put(Mockito.eq(LogicalDatastoreType.OPERATIONAL), any(YangInstanceIdentifier.class),
144                 any(NormalizedNode.class));
145
146         mapEntryNode = Mockito.mock(MapEntryNode.class);
147     }
148
149     @Override
150     protected final AbstractDataBrokerTestCustomizer createDataBrokerTestCustomizer() {
151         final AbstractDataBrokerTestCustomizer customizer = super.createDataBrokerTestCustomizer();
152         context = customizer.getAdapterContext();
153         return customizer;
154     }
155
156     @Test
157     public void routesCaseClass() {
158         assertEquals(Ipv4RoutesCase.class, ribSupportTestImp.routesCaseClass());
159     }
160
161     @Test
162     public void routesContainerClass() {
163         assertEquals(Ipv4Routes.class, ribSupportTestImp.routesContainerClass());
164     }
165
166     @Test
167     public void routesListClass() {
168         assertEquals(Ipv4Route.class, ribSupportTestImp.routesListClass());
169     }
170
171     @Test
172     public void routeQName() {
173         assertEquals(Ipv4Route.QNAME, ribSupportTestImp.routeQName());
174     }
175
176     @Test
177     public void routeNid() {
178         assertEquals(new NodeIdentifier(Ipv4Route.QNAME),ribSupportTestImp.routeNid());
179     }
180
181     @Test
182     public void getTablesKey() {
183         assertEquals(new TablesKey(Ipv4AddressFamily.VALUE, UnicastSubsequentAddressFamily.VALUE),
184             ribSupportTestImp.getTablesKey());
185     }
186
187     @Test
188     public void routesContainerIdentifier() {
189         assertEquals(IPV4_ROUTES_IDENTIFIER, ribSupportTestImp.routesContainerIdentifier());
190     }
191
192     @Test
193     public void routeAttributesIdentifier() {
194         assertEquals(new NodeIdentifier(QName.create(Ipv4Routes.QNAME,
195                 Attributes.QNAME.getLocalName().intern())),ribSupportTestImp.routeAttributesIdentifier());
196     }
197
198     @Test
199     public void routePath() {
200         assertEquals(LOC_RIB_TARGET.node(ROUTES_IDENTIFIER)
201                         .node(Ipv4Routes.QNAME).node(Ipv4Route.QNAME).node(PREFIX_NII),
202                 ribSupportTestImp.routePath(LOC_RIB_TARGET, PREFIX_NII));
203     }
204
205     @Test
206     public void changedRoutes() {
207         assertTrue(ribSupportTestImp.changedRoutes(emptyTree).isEmpty());
208         assertTrue(ribSupportTestImp.changedRoutes(emptySubTree).isEmpty());
209         assertNotNull(ribSupportTestImp.changedRoutes(subTree));
210     }
211
212     @Test
213     public void putRoutes() {
214         ribSupportTestImp.putRoutes(tx, LOC_RIB_TARGET, nlri, attributes);
215         assertFalse(routesMap.isEmpty());
216     }
217
218     @Test
219     public void deleteRoutes() {
220         ribSupportTestImp.deleteRoutes(tx, LOC_RIB_TARGET, nlri);
221         assertTrue(routesMap.isEmpty());
222     }
223
224
225     @Test
226     public void buildUpdate() {
227         final Ipv4NextHopCase nextHop = new Ipv4NextHopCaseBuilder().setIpv4NextHop(new Ipv4NextHopBuilder()
228                 .setGlobal(new Ipv4AddressNoZone("10.0.0.2")).build()).build();
229         final Attributes attr = new AttributesBuilder().setCNextHop(nextHop).build();
230         final Collection<MapEntryNode> routes = new HashSet<>();
231
232         assertEquals(new UpdateBuilder().setAttributes(new AttributesBuilder().build()).build(),
233                ribSupportTestImp.buildUpdate(routes, routes, attr));
234
235         routes.add(mapEntryNode);
236         final MpReachNlri mpReach = new MpReachNlriBuilder().setAfi(Ipv4AddressFamily.VALUE)
237                 .setSafi(UnicastSubsequentAddressFamily.VALUE)
238                 .setCNextHop(nextHop).setAdvertizedRoutes(new AdvertizedRoutesBuilder().build()).build();
239
240         final Attributes attMpR = new AttributesBuilder().addAugmentation(
241             new AttributesReachBuilder().setMpReachNlri(mpReach).build()).build();
242         assertEquals(new UpdateBuilder().setAttributes(attMpR).build(),
243                ribSupportTestImp.buildUpdate(routes, Set.of(), attr));
244
245         final MpUnreachNlri mpUnreach = new MpUnreachNlriBuilder()
246                 .setAfi(Ipv4AddressFamily.VALUE)
247                 .setSafi(UnicastSubsequentAddressFamily.VALUE)
248                 .setWithdrawnRoutes(new WithdrawnRoutesBuilder().build())
249                 .build();
250
251         final Attributes attMpU = new AttributesBuilder().addAugmentation(
252                 new AttributesUnreachBuilder().setMpUnreachNlri(mpUnreach).build()).build();
253         assertEquals(new UpdateBuilder().setAttributes(attMpU).build(),
254                ribSupportTestImp.buildUpdate(Set.of(), routes, attr));
255     }
256 }