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 org.junit.Assert.assertArrayEquals;
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertTrue;
22 import static org.junit.Assert.fail;
23 import static org.mockito.Matchers.any;
24 import static org.mockito.Matchers.eq;
25 import static org.mockito.Mockito.doReturn;
26 import static org.mockito.Mockito.times;
27 import static org.mockito.Mockito.verify;
28 import static org.mockito.Mockito.when;
30 import com.google.common.net.InetAddresses;
31 import io.fd.honeycomb.translate.v3po.DisabledInterfacesManager;
32 import io.fd.honeycomb.translate.vpp.util.NamingContext;
33 import io.fd.honeycomb.translate.write.WriteFailedException;
34 import io.fd.honeycomb.vpp.test.write.WriterCustomizerTest;
35 import org.junit.Test;
36 import org.mockito.ArgumentCaptor;
37 import org.mockito.Mock;
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.Ipv4Address;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanVni;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.Vxlan;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.VxlanBuilder;
47 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
48 import org.openvpp.jvpp.VppBaseCallException;
49 import org.openvpp.jvpp.VppInvocationException;
50 import org.openvpp.jvpp.core.dto.VxlanAddDelTunnel;
51 import org.openvpp.jvpp.core.dto.VxlanAddDelTunnelReply;
53 public class VxlanCustomizerTest extends WriterCustomizerTest {
55 private static final byte ADD_VXLAN = 1;
56 private static final byte DEL_VXLAN = 0;
59 private DisabledInterfacesManager disableContext;
61 private VxlanCustomizer customizer;
62 private String ifaceName;
63 private InstanceIdentifier<Vxlan> id;
66 public void setUp() throws Exception {
67 InterfaceTypeTestUtils.setupWriteContext(writeContext,
68 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanTunnel.class);
71 new VxlanCustomizer(api, new NamingContext("generateInterfaceNAme", "test-instance"), disableContext);
74 id = InstanceIdentifier.create(Interfaces.class).child(Interface.class, new InterfaceKey(ifaceName))
75 .augmentation(VppInterfaceAugmentation.class).child(Vxlan.class);
78 private void whenVxlanAddDelTunnelThenSuccess() {
79 when(api.vxlanAddDelTunnel(any(VxlanAddDelTunnel.class))).thenReturn(future(new VxlanAddDelTunnelReply()));
82 private void whenVxlanAddDelTunnelThenFailure() {
83 doReturn(failedFuture()).when(api).vxlanAddDelTunnel(any(VxlanAddDelTunnel.class));
86 private VxlanAddDelTunnel verifyVxlanAddDelTunnelWasInvoked(final Vxlan vxlan) throws VppInvocationException {
87 ArgumentCaptor<VxlanAddDelTunnel> argumentCaptor = ArgumentCaptor.forClass(VxlanAddDelTunnel.class);
88 verify(api).vxlanAddDelTunnel(argumentCaptor.capture());
89 final VxlanAddDelTunnel actual = argumentCaptor.getValue();
90 assertEquals(0, actual.isIpv6);
91 assertEquals(-1, actual.decapNextIndex);
92 assertArrayEquals(InetAddresses.forString(vxlan.getSrc().getIpv4Address().getValue()).getAddress(),
94 assertArrayEquals(InetAddresses.forString(vxlan.getDst().getIpv4Address().getValue()).getAddress(),
96 assertEquals(vxlan.getEncapVrfId().intValue(), actual.encapVrfId);
97 assertEquals(vxlan.getVni().getValue().intValue(), actual.vni);
101 private void verifyVxlanAddWasInvoked(final Vxlan vxlan) throws VppInvocationException {
102 final VxlanAddDelTunnel actual = verifyVxlanAddDelTunnelWasInvoked(vxlan);
103 assertEquals(ADD_VXLAN, actual.isAdd);
106 private void verifyVxlanDeleteWasInvoked(final Vxlan vxlan) throws VppInvocationException {
107 final VxlanAddDelTunnel actual = verifyVxlanAddDelTunnelWasInvoked(vxlan);
108 assertEquals(DEL_VXLAN, actual.isAdd);
111 private static Vxlan generateVxlan(long vni) {
112 final VxlanBuilder builder = new VxlanBuilder();
113 builder.setSrc(new IpAddress(new Ipv4Address("192.168.20.10")));
114 builder.setDst(new IpAddress(new Ipv4Address("192.168.20.11")));
115 builder.setEncapVrfId(Long.valueOf(123));
116 builder.setVni(new VxlanVni(Long.valueOf(vni)));
117 return builder.build();
120 private static Vxlan generateVxlan() {
121 return generateVxlan(Long.valueOf(11));
125 public void testWriteCurrentAttributes() throws Exception {
126 final Vxlan vxlan = generateVxlan();
128 whenVxlanAddDelTunnelThenSuccess();
129 noMappingDefined(mappingContext, ifaceName, "test-instance");
131 customizer.writeCurrentAttributes(id, vxlan, writeContext);
132 verifyVxlanAddWasInvoked(vxlan);
133 verify(mappingContext).put(eq(mappingIid(ifaceName, "test-instance")), eq(mapping(ifaceName, 0).get()));
137 public void testWriteCurrentAttributesWithExistingVxlanPlaceholder() throws Exception {
138 final Vxlan vxlan = generateVxlan();
140 whenVxlanAddDelTunnelThenSuccess();
141 noMappingDefined(mappingContext, ifaceName, "test-instance");
142 doReturn(true).when(disableContext).isInterfaceDisabled(0, mappingContext);
144 customizer.writeCurrentAttributes(id, vxlan, writeContext);
145 verifyVxlanAddWasInvoked(vxlan);
146 verify(mappingContext).put(eq(mappingIid(ifaceName, "test-instance")), eq(mapping(ifaceName, 0).get()));
147 verify(disableContext).removeDisabledInterface(0, mappingContext);
151 public void testWriteCurrentAttributesMappingAlreadyPresent() throws Exception {
152 final Vxlan vxlan = generateVxlan();
153 final int ifaceId = 0;
155 whenVxlanAddDelTunnelThenSuccess();
156 defineMapping(mappingContext, ifaceName, ifaceId, "test-instance");
158 customizer.writeCurrentAttributes(id, vxlan, writeContext);
159 verifyVxlanAddWasInvoked(vxlan);
161 // Remove the first mapping before putting in the new one
162 verify(mappingContext).delete(eq(mappingIid(ifaceName, "test-instance")));
163 verify(mappingContext)
164 .put(eq(mappingIid(ifaceName, "test-instance")), eq(mapping(ifaceName, ifaceId).get()));
168 public void testWriteCurrentAttributesFailed() throws Exception {
169 final Vxlan vxlan = generateVxlan();
171 whenVxlanAddDelTunnelThenFailure();
174 customizer.writeCurrentAttributes(id, vxlan, writeContext);
175 } catch (WriteFailedException.CreateFailedException e) {
176 assertTrue(e.getCause() instanceof VppBaseCallException);
177 verifyVxlanAddWasInvoked(vxlan);
178 // Mapping not stored due to failure
179 verify(mappingContext, times(0))
180 .put(eq(mappingIid(ifaceName, "test-instance")), eq(mapping(ifaceName, 0).get()));
183 fail("WriteFailedException.CreateFailedException was expected");
187 public void testUpdateCurrentAttributes() throws Exception {
189 customizer.updateCurrentAttributes(id, generateVxlan(10), generateVxlan(11), writeContext);
190 } catch (WriteFailedException.UpdateFailedException e) {
191 assertEquals(UnsupportedOperationException.class, e.getCause().getClass());
194 fail("WriteFailedException.UpdateFailedException was expected");
198 public void testDeleteCurrentAttributes() throws Exception {
199 final Vxlan vxlan = generateVxlan();
201 whenVxlanAddDelTunnelThenSuccess();
202 defineMapping(mappingContext, ifaceName, 1, "test-instance");
204 customizer.deleteCurrentAttributes(id, vxlan, writeContext);
205 verifyVxlanDeleteWasInvoked(vxlan);
206 verify(mappingContext).delete(eq(mappingIid(ifaceName, "test-instance")));
207 verify(disableContext).disableInterface(1, mappingContext);
211 public void testDeleteCurrentAttributesaFailed() throws Exception {
212 final Vxlan vxlan = generateVxlan();
214 whenVxlanAddDelTunnelThenFailure();
215 defineMapping(mappingContext, ifaceName, 1, "test-instance");
218 customizer.deleteCurrentAttributes(id, vxlan, writeContext);
219 } catch (WriteFailedException.DeleteFailedException e) {
220 assertTrue(e.getCause() instanceof VppBaseCallException);
221 verifyVxlanDeleteWasInvoked(vxlan);
222 verify(mappingContext, times(0)).delete(eq(mappingIid(ifaceName, "test-instance")));
225 fail("WriteFailedException.DeleteFailedException was expected");