2 * Copyright (c) 2016 Cisco and/or its affiliates.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package io.fd.honeycomb.translate.v3po.interfaces;
19 import static io.fd.honeycomb.translate.v3po.test.ContextTestUtils.getMapping;
20 import static io.fd.honeycomb.translate.v3po.test.ContextTestUtils.getMappingIid;
21 import static org.junit.Assert.assertArrayEquals;
22 import static org.junit.Assert.assertEquals;
23 import static org.junit.Assert.assertTrue;
24 import static org.junit.Assert.fail;
25 import static org.mockito.Matchers.any;
26 import static org.mockito.Matchers.eq;
27 import static org.mockito.Mockito.doReturn;
28 import static org.mockito.Mockito.times;
29 import static org.mockito.Mockito.verify;
30 import static org.mockito.Mockito.when;
32 import com.google.common.net.InetAddresses;
33 import io.fd.honeycomb.translate.v3po.DisabledInterfacesManager;
34 import io.fd.honeycomb.translate.v3po.test.ContextTestUtils;
35 import io.fd.honeycomb.translate.v3po.util.NamingContext;
36 import io.fd.honeycomb.translate.write.WriteFailedException;
37 import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest;
38 import org.junit.Test;
39 import org.mockito.ArgumentCaptor;
40 import org.mockito.Mock;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanVni;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.Vxlan;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.VxlanBuilder;
50 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
51 import org.openvpp.jvpp.VppBaseCallException;
52 import org.openvpp.jvpp.VppInvocationException;
53 import org.openvpp.jvpp.core.dto.VxlanAddDelTunnel;
54 import org.openvpp.jvpp.core.dto.VxlanAddDelTunnelReply;
56 public class VxlanCustomizerTest extends WriterCustomizerTest {
58 private static final byte ADD_VXLAN = 1;
59 private static final byte DEL_VXLAN = 0;
62 private DisabledInterfacesManager disableContext;
64 private VxlanCustomizer customizer;
65 private String ifaceName;
66 private InstanceIdentifier<Vxlan> id;
69 public void setUp() throws Exception {
70 InterfaceTypeTestUtils.setupWriteContext(writeContext,
71 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanTunnel.class);
74 new VxlanCustomizer(api, new NamingContext("generateInterfaceNAme", "test-instance"), disableContext);
77 id = InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(ifaceName))
78 .augmentation(VppInterfaceAugmentation.class).child(Vxlan.class);
81 private void whenVxlanAddDelTunnelThenSuccess() {
82 when(api.vxlanAddDelTunnel(any(VxlanAddDelTunnel.class))).thenReturn(future(new VxlanAddDelTunnelReply()));
85 private void whenVxlanAddDelTunnelThenFailure() {
86 doReturn(failedFuture()).when(api).vxlanAddDelTunnel(any(VxlanAddDelTunnel.class));
89 private VxlanAddDelTunnel verifyVxlanAddDelTunnelWasInvoked(final Vxlan vxlan) throws VppInvocationException {
90 ArgumentCaptor<VxlanAddDelTunnel> argumentCaptor = ArgumentCaptor.forClass(VxlanAddDelTunnel.class);
91 verify(api).vxlanAddDelTunnel(argumentCaptor.capture());
92 final VxlanAddDelTunnel actual = argumentCaptor.getValue();
93 assertEquals(0, actual.isIpv6);
94 assertEquals(-1, actual.decapNextIndex);
95 assertArrayEquals(InetAddresses.forString(vxlan.getSrc().getIpv4Address().getValue()).getAddress(),
97 assertArrayEquals(InetAddresses.forString(vxlan.getDst().getIpv4Address().getValue()).getAddress(),
99 assertEquals(vxlan.getEncapVrfId().intValue(), actual.encapVrfId);
100 assertEquals(vxlan.getVni().getValue().intValue(), actual.vni);
104 private void verifyVxlanAddWasInvoked(final Vxlan vxlan) throws VppInvocationException {
105 final VxlanAddDelTunnel actual = verifyVxlanAddDelTunnelWasInvoked(vxlan);
106 assertEquals(ADD_VXLAN, actual.isAdd);
109 private void verifyVxlanDeleteWasInvoked(final Vxlan vxlan) throws VppInvocationException {
110 final VxlanAddDelTunnel actual = verifyVxlanAddDelTunnelWasInvoked(vxlan);
111 assertEquals(DEL_VXLAN, actual.isAdd);
114 private static Vxlan generateVxlan(long vni) {
115 final VxlanBuilder builder = new VxlanBuilder();
116 builder.setSrc(new IpAddress(new Ipv4Address("192.168.20.10")));
117 builder.setDst(new IpAddress(new Ipv4Address("192.168.20.11")));
118 builder.setEncapVrfId(Long.valueOf(123));
119 builder.setVni(new VxlanVni(Long.valueOf(vni)));
120 return builder.build();
123 private static Vxlan generateVxlan() {
124 return generateVxlan(Long.valueOf(11));
128 public void testWriteCurrentAttributes() throws Exception {
129 final Vxlan vxlan = generateVxlan();
131 whenVxlanAddDelTunnelThenSuccess();
132 ContextTestUtils.mockEmptyMapping(mappingContext, ifaceName, "test-instance");
134 customizer.writeCurrentAttributes(id, vxlan, writeContext);
135 verifyVxlanAddWasInvoked(vxlan);
136 verify(mappingContext).put(eq(getMappingIid(ifaceName, "test-instance")), eq(getMapping(ifaceName, 0).get()));
140 public void testWriteCurrentAttributesWithExistingVxlanPlaceholder() throws Exception {
141 final Vxlan vxlan = generateVxlan();
143 whenVxlanAddDelTunnelThenSuccess();
144 ContextTestUtils.mockEmptyMapping(mappingContext, ifaceName, "test-instance");
145 doReturn(true).when(disableContext).isInterfaceDisabled(0, mappingContext);
147 customizer.writeCurrentAttributes(id, vxlan, writeContext);
148 verifyVxlanAddWasInvoked(vxlan);
149 verify(mappingContext).put(eq(getMappingIid(ifaceName, "test-instance")), eq(getMapping(ifaceName, 0).get()));
150 verify(disableContext).removeDisabledInterface(0, mappingContext);
154 public void testWriteCurrentAttributesMappingAlreadyPresent() throws Exception {
155 final Vxlan vxlan = generateVxlan();
156 final int ifaceId = 0;
158 whenVxlanAddDelTunnelThenSuccess();
159 ContextTestUtils.mockMapping(mappingContext, ifaceName, ifaceId, "test-instance");
161 customizer.writeCurrentAttributes(id, vxlan, writeContext);
162 verifyVxlanAddWasInvoked(vxlan);
164 // Remove the first mapping before putting in the new one
165 verify(mappingContext).delete(eq(getMappingIid(ifaceName, "test-instance")));
166 verify(mappingContext)
167 .put(eq(getMappingIid(ifaceName, "test-instance")), eq(getMapping(ifaceName, ifaceId).get()));
171 public void testWriteCurrentAttributesFailed() throws Exception {
172 final Vxlan vxlan = generateVxlan();
174 whenVxlanAddDelTunnelThenFailure();
177 customizer.writeCurrentAttributes(id, vxlan, writeContext);
178 } catch (WriteFailedException.CreateFailedException e) {
179 assertTrue(e.getCause() instanceof VppBaseCallException);
180 verifyVxlanAddWasInvoked(vxlan);
181 // Mapping not stored due to failure
182 verify(mappingContext, times(0))
183 .put(eq(getMappingIid(ifaceName, "test-instance")), eq(getMapping(ifaceName, 0).get()));
186 fail("WriteFailedException.CreateFailedException was expected");
190 public void testUpdateCurrentAttributes() throws Exception {
192 customizer.updateCurrentAttributes(id, generateVxlan(10), generateVxlan(11), writeContext);
193 } catch (WriteFailedException.UpdateFailedException e) {
194 assertEquals(UnsupportedOperationException.class, e.getCause().getClass());
197 fail("WriteFailedException.UpdateFailedException was expected");
201 public void testDeleteCurrentAttributes() throws Exception {
202 final Vxlan vxlan = generateVxlan();
204 whenVxlanAddDelTunnelThenSuccess();
205 ContextTestUtils.mockMapping(mappingContext, ifaceName, 1, "test-instance");
207 customizer.deleteCurrentAttributes(id, vxlan, writeContext);
208 verifyVxlanDeleteWasInvoked(vxlan);
209 verify(mappingContext).delete(eq(getMappingIid(ifaceName, "test-instance")));
210 verify(disableContext).disableInterface(1, mappingContext);
214 public void testDeleteCurrentAttributesaFailed() throws Exception {
215 final Vxlan vxlan = generateVxlan();
217 whenVxlanAddDelTunnelThenFailure();
218 ContextTestUtils.mockMapping(mappingContext, ifaceName, 1, "test-instance");
221 customizer.deleteCurrentAttributes(id, vxlan, writeContext);
222 } catch (WriteFailedException.DeleteFailedException e) {
223 assertTrue(e.getCause() instanceof VppBaseCallException);
224 verifyVxlanDeleteWasInvoked(vxlan);
225 verify(mappingContext, times(0)).delete(eq(getMappingIid(ifaceName, "test-instance")));
228 fail("WriteFailedException.DeleteFailedException was expected");