Optimize DHCP relay processing for VPP
[groupbasedpolicy.git] / renderers / vpp / src / test / java / org / opendaylight / groupbasedpolicy / renderer / vpp / dhcp / DhcpRelayHandlerTest.java
1 /*
2  * Copyright (c) 2017 Cisco Systems. 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.groupbasedpolicy.renderer.vpp.dhcp;
10
11 import java.util.AbstractMap;
12 import java.util.Collections;
13 import java.util.List;
14 import java.util.concurrent.ExecutionException;
15 import java.util.concurrent.locks.ReentrantLock;
16
17 import org.junit.Assert;
18 import org.junit.Before;
19 import org.junit.Test;
20 import org.mockito.Mockito;
21 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
22 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
23 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
24 import org.opendaylight.groupbasedpolicy.renderer.vpp.VppRendererDataBrokerTest;
25 import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.DhcpRelayCommand;
26 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.General;
27 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.MountedDataBrokerProvider;
28 import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory;
29 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
30 import org.opendaylight.vbd.impl.transaction.VbdNetconfTransaction;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev170511.L2BridgeDomain;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev170511.MacAddressType;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev170511.has.subnet.Subnet;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev170511.has.subnet.SubnetBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.Config;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.ConfigBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425._interface.attributes._interface.type.choice.TapCaseBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpoint;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpointBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.dhcp.rev170315.Ipv4;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.dhcp.rev170315.dhcp.attributes.relays.Relay;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.dhcp.rev170315.dhcp.attributes.relays.RelayBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.dhcp.rev170315.dhcp.attributes.relays.RelayKey;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.dhcp.rev170315.relay.attributes.Server;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.dhcp.rev170315.relay.attributes.ServerBuilder;
51 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
52 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
53
54 import com.google.common.base.Optional;
55 import com.google.common.collect.HashMultimap;
56 import com.google.common.collect.SetMultimap;
57
58 public class DhcpRelayHandlerTest extends VppRendererDataBrokerTest {
59
60     public static final String TEST_BD = "testBD";
61     public static final NodeId TEST_NODE = new NodeId("testNode");
62     private static final long RX_VRF_ID = 0L;
63     private static final SetMultimap<String, NodeId> vppNodesByL2Fd = HashMultimap.create();
64     private static final String TEST_L2_CONTEXT_ID = "53064b9c-6dfa-40cd-81aa-02c88289e363";
65     private static final IpAddress GATEWAY_IP_ADDRESS = new IpAddress(new Ipv4Address("10.0.0.1"));
66     private static final IpAddress SERVER_IP_ADDRESS = new IpAddress(new Ipv4Address("10.0.0.2"));
67     private static final String SERVER_MAC_ADDRESS = "fa:16:3e:a1:c5:c3";
68     public static final List<Server> SERVER_LIST_1 =
69         Collections.singletonList(new ServerBuilder().setVrfId(RX_VRF_ID).setAddress(SERVER_IP_ADDRESS).build());
70     public static final DhcpRelayCommand DHCP_RELAY_COMMAND =
71         DhcpRelayCommand.builder().setAddressType(Ipv4.class)
72             .setGatewayIpAddress(GATEWAY_IP_ADDRESS)
73             .setServerIpAddresses(SERVER_LIST_1)
74             .setOperation(General.Operations.PUT)
75             .setRxVrfId(RX_VRF_ID)
76             .build();
77     private static final VppEndpoint VPP_ENDPOINT = new VppEndpointBuilder()
78         .setAddressType(MacAddressType.class)
79         .setAddress(SERVER_MAC_ADDRESS)
80         .setContextType(L2BridgeDomain.class)
81         .setContextId(new ContextId(TEST_L2_CONTEXT_ID))
82         .setInterfaceTypeChoice(new TapCaseBuilder().setDhcpServerAddress(SERVER_IP_ADDRESS).build())
83         .setVppNodeId(TEST_NODE)
84         .build();
85     private static final Config VPP_RENDERER_CONFIG =
86         new ConfigBuilder().setVppEndpoint(Collections.singletonList(VPP_ENDPOINT)).build();
87     private static final Relay RELAY = new RelayBuilder()
88         .setAddressType(Ipv4.class)
89         .setGatewayAddress(GATEWAY_IP_ADDRESS)
90         .setServer(SERVER_LIST_1)
91         .setRxVrfId(RX_VRF_ID)
92         .build();
93     private static final Subnet
94         subnet = new SubnetBuilder()
95         .setDefaultSubnetGatewayIp(GATEWAY_IP_ADDRESS)
96         .setIpPrefix(new IpPrefix(Ipv4Prefix.getDefaultInstance("10.0.0.2/24")))
97         .build();
98     private DataBroker dataBroker;
99     private MountedDataBrokerProvider mountedDataProviderMock;
100
101     @Before
102     public void init() throws ExecutionException, InterruptedException {
103         dataBroker = getDataBroker();
104         mountedDataProviderMock = Mockito.mock(MountedDataBrokerProvider.class);
105         VbdNetconfTransaction.NODE_DATA_BROKER_MAP.put(VppIidFactory.getNetconfNodeIid(TEST_NODE),
106                 new AbstractMap.SimpleEntry<DataBroker,ReentrantLock>(dataBroker, new ReentrantLock()));
107         vppNodesByL2Fd.put(TEST_BD, TEST_NODE);
108         Mockito.when(mountedDataProviderMock.resolveDataBrokerForMountPoint(Mockito.any(InstanceIdentifier.class)))
109             .thenReturn(Optional.of(dataBroker));
110         writeBasicDhcpVppEp();
111     }
112
113     @Test
114     public void createIpv4DhcpRelayTest() throws ExecutionException, InterruptedException {
115         DhcpRelayHandler dhcpRelayHandler = new DhcpRelayHandler(dataBroker);
116
117         List<DhcpRelayCommand> createdIpv4DhcpRelays =
118             dhcpRelayHandler.getCreatedIpv4DhcpRelays(RX_VRF_ID, subnet, vppNodesByL2Fd);
119         createdIpv4DhcpRelays.forEach(dhcpRelayHandler::submitDhcpRelay);
120
121         Optional<Relay> relayOptional = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
122             VppIidFactory.getDhcpRelayIid(DHCP_RELAY_COMMAND.getDhcpBuilder().getKey()),
123             dataBroker.newReadOnlyTransaction());
124         Assert.assertTrue(relayOptional.isPresent());
125         Assert.assertEquals(RELAY, relayOptional.get());
126     }
127
128     @Test
129     public void createIpv4DhcpRelayTestWithNullServerIp() throws ExecutionException, InterruptedException {
130         DhcpRelayHandler dhcpRelayHandler = new DhcpRelayHandler(dataBroker);
131
132         Subnet subnet1 = new SubnetBuilder(subnet).setDefaultSubnetGatewayIp(null).build();
133
134         List<DhcpRelayCommand> createdIpv4DhcpRelays =
135         dhcpRelayHandler.getCreatedIpv4DhcpRelays(RX_VRF_ID, subnet1, vppNodesByL2Fd);
136         createdIpv4DhcpRelays.forEach(dhcpRelayHandler::submitDhcpRelay);
137
138         Optional<Relay> relayOptional = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
139             VppIidFactory.getDhcpRelayIid(DHCP_RELAY_COMMAND.getDhcpBuilder().getKey()),
140             dataBroker.newReadOnlyTransaction());
141         Assert.assertFalse(relayOptional.isPresent());
142     }
143
144     @Test
145     public void deleteIpv4DhcpRelayTest() throws ExecutionException, InterruptedException {
146         DhcpRelayHandler dhcpRelayHandler = new DhcpRelayHandler(dataBroker);
147         writeBasicRelay();
148
149         Optional<Relay> relayOptional = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
150             VppIidFactory.getDhcpRelayIid(DHCP_RELAY_COMMAND.getDhcpBuilder().getKey()),
151             dataBroker.newReadOnlyTransaction());
152         Assert.assertTrue(relayOptional.isPresent());
153         Assert.assertEquals(RELAY, relayOptional.get());
154
155         List<DhcpRelayCommand> deletedIpv4DhcpRelays =
156             dhcpRelayHandler.getDeletedIpv4DhcpRelays(RX_VRF_ID, subnet, vppNodesByL2Fd);
157         deletedIpv4DhcpRelays.forEach(dhcpRelayHandler::submitDhcpRelay);
158
159         relayOptional = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
160             VppIidFactory.getDhcpRelayIid(DHCP_RELAY_COMMAND.getDhcpBuilder().getKey()),
161             dataBroker.newReadOnlyTransaction());
162         Assert.assertFalse(relayOptional.isPresent());
163     }
164
165     private Optional<Relay> writeBasicRelay() throws InterruptedException, ExecutionException {
166         ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();
167         rwTx.put(LogicalDatastoreType.CONFIGURATION,
168             VppIidFactory.getDhcpRelayIid(new RelayKey(Ipv4.class, RX_VRF_ID)), RELAY, true);
169         rwTx.submit().get();
170
171         return DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
172             VppIidFactory.getDhcpRelayIid(new RelayKey(Ipv4.class, RX_VRF_ID)),
173             dataBroker.newReadOnlyTransaction());
174     }
175
176     private Optional<Config> writeBasicDhcpVppEp() throws InterruptedException, ExecutionException {
177         ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();
178         rwTx.put(LogicalDatastoreType.CONFIGURATION,
179             VppIidFactory.getVppRendererConfig(), VPP_RENDERER_CONFIG, true);
180         rwTx.submit().get();
181
182         return DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, VppIidFactory.getVppRendererConfig(),
183             dataBroker.newReadOnlyTransaction());
184     }
185 }