Migrate boolean getters
[bgpcep.git] / pcep / tunnel / tunnel-provider / src / test / java / org / opendaylight / bgpcep / pcep / tunnel / provider / TunnelProgrammingTest.java
1 /*
2  * Copyright (c) 2014 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.bgpcep.pcep.tunnel.provider;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNotNull;
12 import static org.mockito.ArgumentMatchers.any;
13 import static org.mockito.Mockito.doAnswer;
14 import static org.mockito.Mockito.doNothing;
15 import static org.mockito.Mockito.doReturn;
16
17 import com.google.common.util.concurrent.ListenableFuture;
18 import java.util.Collections;
19 import java.util.List;
20 import java.util.concurrent.ExecutionException;
21 import java.util.concurrent.Executor;
22 import org.junit.Before;
23 import org.junit.Test;
24 import org.junit.runner.RunWith;
25 import org.mockito.ArgumentMatchers;
26 import org.mockito.Mock;
27 import org.mockito.Mockito;
28 import org.mockito.junit.MockitoJUnitRunner;
29 import org.opendaylight.bgpcep.programming.spi.Instruction;
30 import org.opendaylight.bgpcep.programming.spi.InstructionScheduler;
31 import org.opendaylight.bgpcep.programming.spi.SchedulerException;
32 import org.opendaylight.mdsal.binding.api.RpcConsumerRegistry;
33 import org.opendaylight.mdsal.binding.api.RpcProviderService;
34 import org.opendaylight.mdsal.binding.api.WriteTransaction;
35 import org.opendaylight.mdsal.binding.dom.adapter.test.AbstractConcurrentDataBrokerTest;
36 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
37 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
38 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.Bandwidth;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.topology.rev140113.NetworkTopologyRef;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev200720.AdministrativeStatus;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev200720.PcepCreateP2pTunnelInput1Builder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev200720.PcepUpdateTunnelInput1Builder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.ClassType;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.endpoints.address.family.Ipv4Case;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.endpoints.address.family.ipv4._case.Ipv4;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev181109.explicit.route.object.ero.Subobject;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev150720.InstructionStatus;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.programming.rev150720.SubmitInstructionInput;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.basic.explicit.route.subobjects.subobject.type.IpPrefixCase;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.basic.explicit.route.subobjects.subobject.type.IpPrefixCaseBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.basic.explicit.route.subobjects.subobject.type.ip.prefix._case.IpPrefixBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.AddLspInput;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.AddLspOutput;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.NetworkTopologyPcepService;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.RemoveLspInput;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.RemoveLspOutput;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.UpdateLspInput;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.UpdateLspOutput;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.add.lsp.args.Arguments;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.p2p.rev130819.tunnel.p2p.path.cfg.attributes.ExplicitHops;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.p2p.rev130819.tunnel.p2p.path.cfg.attributes.ExplicitHopsBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev181109.PcepCreateP2pTunnelInputBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev181109.PcepDestroyTunnelInputBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.programming.rev181109.PcepUpdateTunnelInputBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.rev181109.ExplicitHops1Builder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.rev181109.Link1Builder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.rev181109.SupportingNode1Builder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.pcep.rev181109.tunnel.pcep.supporting.node.attributes.PathComputationClientBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.programming.rev130930.create.p2p.tunnel.input.DestinationBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.tunnel.programming.rev130930.create.p2p.tunnel.input.SourceBuilder;
75 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.LinkId;
76 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
77 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
78 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
79 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
80 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
81 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
82 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
83 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link;
84 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.LinkBuilder;
85 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.LinkKey;
86 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
87 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
88 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
89 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.node.attributes.SupportingNodeBuilder;
90 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.nt.l3.unicast.igp.topology.rev131021.TerminationPoint1Builder;
91 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.nt.l3.unicast.igp.topology.rev131021.igp.termination.point.attributes.IgpTerminationPointAttributesBuilder;
92 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.nt.l3.unicast.igp.topology.rev131021.igp.termination.point.attributes.igp.termination.point.attributes.termination.point.type.IpBuilder;
93 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
94 import org.opendaylight.yangtools.yang.binding.util.BindingMap;
95 import org.opendaylight.yangtools.yang.common.RpcResult;
96 import org.opendaylight.yangtools.yang.common.Uint32;
97 import org.opendaylight.yangtools.yang.common.Uint8;
98 import org.osgi.framework.BundleContext;
99
100 @RunWith(MockitoJUnitRunner.StrictStubs.class)
101 public class TunnelProgrammingTest extends AbstractConcurrentDataBrokerTest {
102
103     private static final TopologyId TOPOLOGY_ID = new TopologyId("tunnel-topo");
104     private static final InstanceIdentifier<Topology> TOPO_IID = InstanceIdentifier.builder(NetworkTopology.class)
105             .child(Topology.class, new TopologyKey(TOPOLOGY_ID)).build();
106
107     private static final String NODE1_IPV4 = "127.0.0.1";
108     private static final NodeId NODE1_ID = new NodeId("pcc://" + NODE1_IPV4);
109     private static final TpId TP1_ID = new TpId(NODE1_IPV4);
110
111     private static final String NODE2_IPV4 = "127.0.0.10";
112     private static final NodeId NODE2_ID = new NodeId("pcc://" + NODE2_IPV4);
113     private static final TpId TP2_ID = new TpId(NODE2_IPV4);
114
115     private static final LinkId LINK1_ID = new LinkId("link1");
116
117     private static final String IPV4_PREFIX1 = "195.20.160.40/32";
118     private static final String IPV4_PREFIX2 = "201.20.160.43/32";
119
120     @Mock
121     private NetworkTopologyPcepService topologyService;
122     @Mock
123     private InstructionScheduler scheduler;
124     @Mock
125     private ListenableFuture<Instruction> instructionFuture;
126     @Mock
127     private Instruction instruction;
128     @Mock
129     private ClusterSingletonServiceProvider cssp;
130     @Mock
131     private RpcProviderService rpr;
132     @Mock
133     private RpcConsumerRegistry rpcs;
134     @Mock
135     private BundleContext bundleContext;
136
137     private TunnelProgramming tunnelProgramming;
138
139     private AddLspInput addLspInput;
140     private UpdateLspInput updateLspInput;
141     private RemoveLspInput removeLspInput;
142
143     @Mock
144     private ListenableFuture<RpcResult<AddLspOutput>> futureAddLspOutput;
145     @Mock
146     private ListenableFuture<RpcResult<UpdateLspOutput>> futureUpdateLspOutput;
147     @Mock
148     private ListenableFuture<RpcResult<RemoveLspOutput>> futureRemoveLspOutput;
149
150     private static Node createNode(final NodeId nodeId, final TpId tpId, final String ipv4Address) {
151         return new NodeBuilder()
152             .setNodeId(nodeId)
153             .setTerminationPoint(BindingMap.of(new TerminationPointBuilder()
154                 .setTpId(tpId)
155                 .addAugmentation(new TerminationPoint1Builder()
156                     .setIgpTerminationPointAttributes(new IgpTerminationPointAttributesBuilder()
157                         .setTerminationPointType(new IpBuilder()
158                             .setIpAddress(Collections.singletonList(new IpAddress(new Ipv4Address(ipv4Address))))
159                             .build())
160                         .build())
161                     .build())
162                 .build()))
163             .setSupportingNode(BindingMap.of(new SupportingNodeBuilder()
164                 .setTopologyRef(new TopologyId("dummy"))
165                 .setNodeRef(nodeId)
166                 .addAugmentation(new SupportingNode1Builder()
167                     .setPathComputationClient(new PathComputationClientBuilder().setControlling(true).build())
168                     .build())
169                 .build()))
170             .build();
171     }
172
173     private static ExplicitHops createExplicitHop(final String ipv4Prefix, final Uint32 order) {
174         return new ExplicitHopsBuilder()
175                 .setOrder(order)
176                 .addAugmentation(new ExplicitHops1Builder()
177                     .setSubobjectType(new IpPrefixCaseBuilder().setIpPrefix(new IpPrefixBuilder()
178                         .setIpPrefix(new IpPrefix(new Ipv4Prefix(ipv4Prefix))).build()).build())
179                     .build())
180                 .build();
181     }
182
183     @Before
184     public void setUp() throws SchedulerException, InterruptedException, ExecutionException {
185         doReturn(true).when(instruction).checkedExecutionStart();
186         doNothing().when(instruction).executionCompleted(InstructionStatus.Failed, null);
187         doAnswer(invocation -> {
188             invocation.getArgument(0, Runnable.class).run();
189             return null;
190         }).when(instructionFuture).addListener(ArgumentMatchers.any(Runnable.class), Mockito.any(Executor.class));
191         doReturn(false).when(futureAddLspOutput).isCancelled();
192         doAnswer(invocation -> {
193             invocation.getArgument(0, Runnable.class).run();
194             return null;
195         }).when(futureAddLspOutput).addListener(any(Runnable.class), any(Executor.class));
196         doReturn(false).when(futureUpdateLspOutput).isCancelled();
197         doAnswer(invocation -> {
198             invocation.getArgument(0, Runnable.class).run();
199             return null;
200         }).when(futureUpdateLspOutput).addListener(any(Runnable.class), any(Executor.class));
201         doReturn(false).when(futureRemoveLspOutput).isCancelled();
202         doAnswer(invocation -> {
203             invocation.getArgument(0, Runnable.class).run();
204             return null;
205         }).when(futureRemoveLspOutput).addListener(any(Runnable.class), any(Executor.class));
206         doAnswer(invocation -> {
207             addLspInput = invocation.getArgument(0);
208             return futureAddLspOutput;
209         }).when(topologyService).addLsp(any(AddLspInput.class));
210         doAnswer(invocation -> {
211             updateLspInput = invocation.getArgument(0);
212             return futureUpdateLspOutput;
213         }).when(topologyService).updateLsp(any(UpdateLspInput.class));
214         doAnswer(invocation -> {
215             removeLspInput = invocation.getArgument(0);
216             return futureRemoveLspOutput;
217         }).when(topologyService).removeLsp(any(RemoveLspInput.class));
218         doReturn(instruction).when(instructionFuture).get();
219         doReturn(true).when(instructionFuture).isDone();
220         doReturn(instructionFuture).when(scheduler)
221                 .scheduleInstruction(any(SubmitInstructionInput.class));
222
223         doReturn(topologyService).when(rpcs)
224                 .getRpcService(NetworkTopologyPcepService.class);
225
226         createInitialTopology();
227         tunnelProgramming = new TunnelProgramming(scheduler,
228             new TunnelProviderDependencies(getDataBroker(), cssp, rpr, rpcs, bundleContext));
229     }
230
231     @Test
232     public void testTunnelProgramming() throws InterruptedException, ExecutionException {
233         final Bandwidth bwd = new Bandwidth(new byte[] { 0x00, 0x00, 0x00, (byte) 0xff });
234         final ClassType classType = new ClassType(Uint8.ONE);
235         final String tunnelName = "create-tunnel";
236         final NetworkTopologyRef topologyRef = new NetworkTopologyRef(TOPO_IID);
237         // create tunnel
238         tunnelProgramming.pcepCreateP2pTunnel(new PcepCreateP2pTunnelInputBuilder()
239             .setDestination(new DestinationBuilder().setNode(NODE2_ID).setTp(TP2_ID).build())
240             .setSource(new SourceBuilder().setNode(NODE1_ID).setTp(TP1_ID).build())
241             .setNetworkTopologyRef(topologyRef)
242             .setBandwidth(bwd)
243             .setClassType(classType)
244             .setSymbolicPathName(tunnelName)
245             .addAugmentation(new PcepCreateP2pTunnelInput1Builder()
246                 .setAdministrativeStatus(AdministrativeStatus.Active)
247                 .build())
248             .build());
249         //check add-lsp input
250         assertNotNull(addLspInput);
251         assertEquals(tunnelName, addLspInput.getName());
252         final Arguments agrs = addLspInput.getArguments();
253         assertNotNull(agrs);
254         assertEquals(bwd, agrs.getBandwidth().getBandwidth());
255         assertEquals(classType, agrs.getClassType().getClassType());
256         final Ipv4 ipv4Endpoints = ((Ipv4Case) agrs.getEndpointsObj().getAddressFamily()).getIpv4();
257         assertEquals(NODE1_IPV4, ipv4Endpoints.getSourceIpv4Address().getValue());
258         assertEquals(NODE2_IPV4, ipv4Endpoints.getDestinationIpv4Address().getValue());
259         assertEquals(NODE1_ID.getValue(), addLspInput.getNode().getValue());
260         createLink();
261
262         // update tunnel
263         tunnelProgramming.pcepUpdateTunnel(new PcepUpdateTunnelInputBuilder()
264             .setNetworkTopologyRef(topologyRef)
265             .setBandwidth(bwd)
266             .setClassType(classType)
267             // We assert on explicit order
268             .setExplicitHops(BindingMap.ordered(
269                 createExplicitHop(IPV4_PREFIX1, Uint32.ONE),
270                 createExplicitHop(IPV4_PREFIX2, Uint32.TWO)))
271             .setLinkId(LINK1_ID)
272             .addAugmentation(new PcepUpdateTunnelInput1Builder()
273                 .setAdministrativeStatus(AdministrativeStatus.Active)
274                 .build())
275             .build());
276         //check update-lsp input
277         assertNotNull(updateLspInput);
278         assertEquals(LINK1_ID.getValue(), updateLspInput.getName());
279         final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev200120.update.lsp
280                 .args.Arguments updArgs = updateLspInput.getArguments();
281         assertEquals(2, updArgs.getEro().nonnullSubobject().size());
282         final List<Subobject> subObjects = updArgs.getEro().nonnullSubobject();
283         final IpPrefixCase prefix1 = (IpPrefixCase) subObjects.get(0).getSubobjectType();
284         final IpPrefixCase prefix2 = (IpPrefixCase) subObjects.get(1).getSubobjectType();
285         assertEquals(IPV4_PREFIX1, prefix1.getIpPrefix().getIpPrefix().getIpv4Prefix().getValue());
286         assertEquals(IPV4_PREFIX2, prefix2.getIpPrefix().getIpPrefix().getIpv4Prefix().getValue());
287
288         // delete tunnel
289         final PcepDestroyTunnelInputBuilder destroyInputBuilder = new PcepDestroyTunnelInputBuilder();
290         destroyInputBuilder.setLinkId(LINK1_ID);
291         destroyInputBuilder.setNetworkTopologyRef(topologyRef);
292         tunnelProgramming.pcepDestroyTunnel(destroyInputBuilder.build());
293         assertNotNull(removeLspInput);
294         assertEquals(LINK1_ID.getValue(), removeLspInput.getName());
295         assertEquals(NODE1_ID, removeLspInput.getNode());
296     }
297
298     private void createInitialTopology() throws InterruptedException, ExecutionException {
299         final WriteTransaction wTx = getDataBroker().newWriteOnlyTransaction();
300         wTx.mergeParentStructurePut(LogicalDatastoreType.OPERATIONAL, TOPO_IID, new TopologyBuilder()
301             .setTopologyId(TOPOLOGY_ID)
302             .setServerProvided(true)
303             .setTopologyId(TOPOLOGY_ID)
304             .setNode(BindingMap.of(createNode(NODE1_ID, TP1_ID, NODE1_IPV4), createNode(NODE2_ID, TP2_ID, NODE2_IPV4)))
305             .build());
306         wTx.commit().get();
307     }
308
309     private void createLink() throws InterruptedException, ExecutionException {
310         final WriteTransaction wTx = getDataBroker().newWriteOnlyTransaction();
311         wTx.mergeParentStructurePut(LogicalDatastoreType.OPERATIONAL,
312             TOPO_IID.child(Link.class, new LinkKey(LINK1_ID)),
313             new LinkBuilder()
314                 .setSource(new org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021
315                     .link.attributes.SourceBuilder().setSourceNode(NODE1_ID).setSourceTp(TP1_ID).build())
316                 .setDestination(new org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021
317                     .link.attributes.DestinationBuilder().setDestNode(NODE2_ID).setDestTp(TP2_ID).build())
318                 .setLinkId(LINK1_ID)
319                 .addAugmentation(new Link1Builder().setSymbolicPathName(LINK1_ID.getValue()).build())
320                 .build());
321         wTx.commit().get();
322     }
323 }